Merge branch 'sync-prototype'
This commit is contained in:
commit
7eb965977a
9
Makefile
9
Makefile
@ -16,18 +16,23 @@ export PATH=$(GOPATH)/bin:$(shell echo $$PATH)
|
|||||||
protos-go:
|
protos-go:
|
||||||
@echo 'Generating protobuf packages (Go)...'
|
@echo 'Generating protobuf packages (Go)...'
|
||||||
# Uncomment if needed
|
# Uncomment if needed
|
||||||
@$(eval P_TIMESTAMP := Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types)
|
|
||||||
@$(eval P_STRUCT := Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types)
|
|
||||||
@$(eval ROOT_PKG := pkg)
|
@$(eval ROOT_PKG := pkg)
|
||||||
@$(eval GOGO_START := GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1)
|
@$(eval GOGO_START := GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1)
|
||||||
@$(eval P_TREE_STORAGE_PATH_PB := $(ROOT_PKG)/acl/treestorage/treepb)
|
@$(eval P_TREE_STORAGE_PATH_PB := $(ROOT_PKG)/acl/treestorage/treepb)
|
||||||
@$(eval P_ACL_CHANGES_PATH_PB := $(ROOT_PKG)/acl/aclchanges/aclpb)
|
@$(eval P_ACL_CHANGES_PATH_PB := $(ROOT_PKG)/acl/aclchanges/aclpb)
|
||||||
@$(eval P_PLAINTEXT_CHANGES_PATH_PB := $(ROOT_PKG)/acl/testutils/testchanges/testchangepb)
|
@$(eval P_PLAINTEXT_CHANGES_PATH_PB := $(ROOT_PKG)/acl/testutils/testchanges/testchangepb)
|
||||||
|
@$(eval P_SYNC_CHANGES_PATH_PB := syncproto)
|
||||||
|
@$(eval P_TIMESTAMP := Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types)
|
||||||
|
@$(eval P_STRUCT := Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types)
|
||||||
|
@$(eval P_ACL_CHANGES := M$(P_ACL_CHANGES_PATH_PB)/protos/aclchanges.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/$(P_ACL_CHANGES_PATH_PB))
|
||||||
|
@$(eval P_TREE_CHANGES := M$(P_TREE_STORAGE_PATH_PB)/protos/tree.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/$(P_TREE_STORAGE_PATH_PB))
|
||||||
|
|
||||||
# use if needed $(eval PKGMAP := $$(P_TIMESTAMP),$$(P_STRUCT))
|
# use if needed $(eval PKGMAP := $$(P_TIMESTAMP),$$(P_STRUCT))
|
||||||
$(GOGO_START) protoc --gogofaster_out=:. $(P_ACL_CHANGES_PATH_PB)/protos/*.proto; mv $(P_ACL_CHANGES_PATH_PB)/protos/*.go $(P_ACL_CHANGES_PATH_PB)
|
$(GOGO_START) protoc --gogofaster_out=:. $(P_ACL_CHANGES_PATH_PB)/protos/*.proto; mv $(P_ACL_CHANGES_PATH_PB)/protos/*.go $(P_ACL_CHANGES_PATH_PB)
|
||||||
$(GOGO_START) protoc --gogofaster_out=:. $(P_TREE_STORAGE_PATH_PB)/protos/*.proto; mv $(P_TREE_STORAGE_PATH_PB)/protos/*.go $(P_TREE_STORAGE_PATH_PB)
|
$(GOGO_START) protoc --gogofaster_out=:. $(P_TREE_STORAGE_PATH_PB)/protos/*.proto; mv $(P_TREE_STORAGE_PATH_PB)/protos/*.go $(P_TREE_STORAGE_PATH_PB)
|
||||||
$(GOGO_START) protoc --gogofaster_out=:. $(P_PLAINTEXT_CHANGES_PATH_PB)/protos/*.proto; mv $(P_PLAINTEXT_CHANGES_PATH_PB)/protos/*.go $(P_PLAINTEXT_CHANGES_PATH_PB)
|
$(GOGO_START) protoc --gogofaster_out=:. $(P_PLAINTEXT_CHANGES_PATH_PB)/protos/*.proto; mv $(P_PLAINTEXT_CHANGES_PATH_PB)/protos/*.go $(P_PLAINTEXT_CHANGES_PATH_PB)
|
||||||
|
$(eval PKGMAP := $$(P_ACL_CHANGES),$$(P_TREE_CHANGES))
|
||||||
|
$(GOGO_START) protoc --gogofaster_out=$(PKGMAP),plugins=grpc:. $(P_SYNC_CHANGES_PATH_PB)/proto/*.proto
|
||||||
|
|
||||||
build:
|
build:
|
||||||
@$(eval FLAGS := $$(shell govvv -flags -pkg github.com/anytypeio/go-anytype-infrastructure-experiments/app))
|
@$(eval FLAGS := $$(shell govvv -flags -pkg github.com/anytypeio/go-anytype-infrastructure-experiments/app))
|
||||||
|
|||||||
@ -7,7 +7,20 @@ import (
|
|||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/config"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/config"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/account"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/api"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/dialer"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/rpc/server"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/secure"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/node"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/document"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/message"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/requesthandler"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/treecache"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
"net/http"
|
||||||
|
_ "net/http/pprof"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -34,6 +47,12 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if debug, ok := os.LookupEnv("ANYPROF"); ok && debug != "" {
|
||||||
|
go func() {
|
||||||
|
http.ListenAndServe(debug, nil)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
// create app
|
// create app
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
a := new(app.App)
|
a := new(app.App)
|
||||||
@ -50,7 +69,7 @@ func main() {
|
|||||||
|
|
||||||
// start app
|
// start app
|
||||||
if err := a.Start(ctx); err != nil {
|
if err := a.Start(ctx); err != nil {
|
||||||
log.Error("can't start app", zap.Error(err))
|
log.Fatal("can't start app", zap.Error(err))
|
||||||
}
|
}
|
||||||
log.Info("app started", zap.String("version", a.Version()))
|
log.Info("app started", zap.String("version", a.Version()))
|
||||||
|
|
||||||
@ -68,8 +87,20 @@ func main() {
|
|||||||
} else {
|
} else {
|
||||||
log.Info("goodbye!")
|
log.Info("goodbye!")
|
||||||
}
|
}
|
||||||
|
time.Sleep(time.Second / 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Bootstrap(a *app.App) {
|
func Bootstrap(a *app.App) {
|
||||||
//a.Register(mycomponent.New())
|
a.Register(account.New()).
|
||||||
|
Register(node.New()).
|
||||||
|
Register(secure.New()).
|
||||||
|
Register(server.New()).
|
||||||
|
Register(dialer.New()).
|
||||||
|
Register(pool.NewPool()).
|
||||||
|
//Register(&example.Example{})
|
||||||
|
Register(document.New()).
|
||||||
|
Register(message.New()).
|
||||||
|
Register(requesthandler.New()).
|
||||||
|
Register(treecache.New()).
|
||||||
|
Register(api.New())
|
||||||
}
|
}
|
||||||
|
|||||||
136
cmd/nodesgen/gen.go
Normal file
136
cmd/nodesgen/gen.go
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/config"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/peer"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
flagNodeMap = flag.String("n", "cmd/nodesgen/nodemap.yml", "path to nodes map file")
|
||||||
|
flagEtcPath = flag.String("e", "etc", "path to etc directory")
|
||||||
|
)
|
||||||
|
|
||||||
|
type NodesMap struct {
|
||||||
|
Nodes []struct {
|
||||||
|
Addresses []string `yaml:"grpcAddresses"`
|
||||||
|
APIPort string `yaml:"apiPort"`
|
||||||
|
} `yaml:"nodes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nodesMap := &NodesMap{}
|
||||||
|
data, err := ioutil.ReadFile(*flagNodeMap)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = yaml.Unmarshal(data, nodesMap)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var configs []config.Config
|
||||||
|
var nodes []config.Node
|
||||||
|
for _, n := range nodesMap.Nodes {
|
||||||
|
cfg, err := genConfig(n.Addresses, n.APIPort)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("could not generate the config file: %s", err.Error()))
|
||||||
|
}
|
||||||
|
configs = append(configs, cfg)
|
||||||
|
|
||||||
|
node := config.Node{
|
||||||
|
PeerId: cfg.Account.PeerId,
|
||||||
|
Address: cfg.GrpcServer.ListenAddrs[0],
|
||||||
|
SigningKey: cfg.Account.SigningKey,
|
||||||
|
EncryptionKey: cfg.Account.EncryptionKey,
|
||||||
|
}
|
||||||
|
nodes = append(nodes, node)
|
||||||
|
}
|
||||||
|
for idx := range configs {
|
||||||
|
configs[idx].Nodes = nodes
|
||||||
|
}
|
||||||
|
|
||||||
|
// saving configs
|
||||||
|
configsPath := fmt.Sprintf("%s/configs", *flagEtcPath)
|
||||||
|
createDir := func() {
|
||||||
|
err := os.Mkdir(configsPath, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("failed to create the configs directory: %v", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(configsPath); os.IsNotExist(err) {
|
||||||
|
createDir()
|
||||||
|
} else {
|
||||||
|
err = os.RemoveAll(configsPath)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("failed to remove the configs directory: %v", err))
|
||||||
|
}
|
||||||
|
createDir()
|
||||||
|
}
|
||||||
|
for _, cfg := range configs {
|
||||||
|
path := fmt.Sprintf("%s/%s.yml", configsPath, cfg.Account.PeerId)
|
||||||
|
bytes, err := yaml.Marshal(cfg)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("could not marshal the keys: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(path, bytes, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("could not write the config to file: %v", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func genConfig(addresses []string, apiPort string) (config.Config, error) {
|
||||||
|
encKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048)
|
||||||
|
if err != nil {
|
||||||
|
return config.Config{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
signKey, _, err := signingkey.GenerateRandomEd25519KeyPair()
|
||||||
|
if err != nil {
|
||||||
|
return config.Config{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
encKeyDecoder := encryptionkey.NewRSAPrivKeyDecoder()
|
||||||
|
signKeyDecoder := signingkey.NewEDPrivKeyDecoder()
|
||||||
|
|
||||||
|
encEncKey, err := encKeyDecoder.EncodeToString(encKey)
|
||||||
|
if err != nil {
|
||||||
|
return config.Config{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
encSignKey, err := signKeyDecoder.EncodeToString(signKey)
|
||||||
|
if err != nil {
|
||||||
|
return config.Config{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
peerID, err := peer.IDFromSigningPubKey(signKey.GetPublic())
|
||||||
|
if err != nil {
|
||||||
|
return config.Config{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.Config{
|
||||||
|
Anytype: config.Anytype{SwarmKey: "/key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec"},
|
||||||
|
GrpcServer: config.GrpcServer{
|
||||||
|
ListenAddrs: addresses,
|
||||||
|
TLS: false,
|
||||||
|
},
|
||||||
|
Account: config.Account{
|
||||||
|
PeerId: peerID.String(),
|
||||||
|
SigningKey: encSignKey,
|
||||||
|
EncryptionKey: encEncKey,
|
||||||
|
},
|
||||||
|
APIServer: config.APIServer{
|
||||||
|
Port: apiPort,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
9
cmd/nodesgen/nodemap.yml
Normal file
9
cmd/nodesgen/nodemap.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
nodes:
|
||||||
|
- grpcAddresses:
|
||||||
|
- "127.0.0.1:4430"
|
||||||
|
- "127.0.0.1:4431"
|
||||||
|
apiPort: "8080"
|
||||||
|
- grpcAddresses:
|
||||||
|
- "127.0.0.1:4432"
|
||||||
|
- "127.0.0.1:4433"
|
||||||
|
apiPort: "8081"
|
||||||
7
config/account.go
Normal file
7
config/account.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type Account struct {
|
||||||
|
PeerId string `yaml:"peerId"`
|
||||||
|
SigningKey string `yaml:"signingKey"`
|
||||||
|
EncryptionKey string `yaml:"encryptionKey"`
|
||||||
|
}
|
||||||
5
config/api.go
Normal file
5
config/api.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type APIServer struct {
|
||||||
|
Port string `yaml:"port"`
|
||||||
|
}
|
||||||
@ -26,6 +26,9 @@ func NewFromFile(path string) (c *Config, err error) {
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Anytype Anytype `yaml:"anytype"`
|
Anytype Anytype `yaml:"anytype"`
|
||||||
GrpcServer GrpcServer `yaml:"grpcServer"`
|
GrpcServer GrpcServer `yaml:"grpcServer"`
|
||||||
|
Account Account `yaml:"account"`
|
||||||
|
APIServer APIServer `yaml:"apiServer"`
|
||||||
|
Nodes []Node `yaml:"nodes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Init(ctx context.Context, a *app.App) (err error) {
|
func (c *Config) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
|||||||
@ -2,4 +2,5 @@ package config
|
|||||||
|
|
||||||
type GrpcServer struct {
|
type GrpcServer struct {
|
||||||
ListenAddrs []string `yaml:"listenAddrs"`
|
ListenAddrs []string `yaml:"listenAddrs"`
|
||||||
|
TLS bool `yaml:"tls"`
|
||||||
}
|
}
|
||||||
|
|||||||
8
config/nodes.go
Normal file
8
config/nodes.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type Node struct {
|
||||||
|
PeerId string `yaml:"peerId"`
|
||||||
|
Address string `yaml:"address"`
|
||||||
|
SigningKey string `yaml:"signingKey"`
|
||||||
|
EncryptionKey string `yaml:"encryptionKey"`
|
||||||
|
}
|
||||||
14
config/peer.go
Normal file
14
config/peer.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type PeerList struct {
|
||||||
|
MyId struct {
|
||||||
|
PeerId string `yaml:"peerId"`
|
||||||
|
PrivKey string `yaml:"privKey"`
|
||||||
|
} `yaml:"myId"`
|
||||||
|
Remote []PeerRemote `yaml:"remote"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PeerRemote struct {
|
||||||
|
PeerId string `yaml:"peerId"`
|
||||||
|
Addr string `yaml:"addr"`
|
||||||
|
}
|
||||||
16
etc/config.1.yml
Normal file
16
etc/config.1.yml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
anytype:
|
||||||
|
swarmKey: "/key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec"
|
||||||
|
|
||||||
|
grpcServer:
|
||||||
|
listenAddrs:
|
||||||
|
- "127.0.0.1:4431"
|
||||||
|
|
||||||
|
peerList:
|
||||||
|
myId:
|
||||||
|
peerId: "12D3KooWA4FLWvrMbCtp2MbzKcC5RRN7HqxxBxPcSADFfzrGiW3U"
|
||||||
|
privKey: "InCGjb55V9+jj2PebUExUuwrpOIBc4hmgk2dSqyk3k4DjmgrdoNVuFe7xCFaFdUVb0RJYj6A+OTp2yXASTmq2w=="
|
||||||
|
remote:
|
||||||
|
- peerId: "12D3KooWHJpSEMQUZCyK8TK181LhjzntWjKfXDr7MWks9cw41R2C"
|
||||||
|
addr: "127.0.0.1:4430"
|
||||||
|
- peerId: "12D3KooWK6c1CPLL4Bvjim9A9SDRmehy12hYjbqX1VASHKfH7W7H"
|
||||||
|
addr: "127.0.0.1:4432"
|
||||||
16
etc/config.2.yml
Normal file
16
etc/config.2.yml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
anytype:
|
||||||
|
swarmKey: "/key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec"
|
||||||
|
|
||||||
|
grpcServer:
|
||||||
|
listenAddrs:
|
||||||
|
- "127.0.0.1:4432"
|
||||||
|
|
||||||
|
peerList:
|
||||||
|
myId:
|
||||||
|
peerId: "12D3KooWK6c1CPLL4Bvjim9A9SDRmehy12hYjbqX1VASHKfH7W7H"
|
||||||
|
privKey: "jynYZBgtM4elT+6e7M5UERTJCZgUd3hDdmQjCqTpApyJ4h53V6TQan4Ru4OXqz+91rCLjpIVdphhaB0l+TvNsA=="
|
||||||
|
remote:
|
||||||
|
- peerId: "12D3KooWA4FLWvrMbCtp2MbzKcC5RRN7HqxxBxPcSADFfzrGiW3U"
|
||||||
|
addr: "127.0.0.1:4431"
|
||||||
|
- peerId: "12D3KooWHJpSEMQUZCyK8TK181LhjzntWjKfXDr7MWks9cw41R2C"
|
||||||
|
addr: "127.0.0.1:4430"
|
||||||
@ -1,6 +1,22 @@
|
|||||||
anytype:
|
anytype:
|
||||||
swarmKey: "/key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec"
|
swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec
|
||||||
|
|
||||||
grpcServer:
|
grpcServer:
|
||||||
listenAddrs:
|
listenAddrs:
|
||||||
- ":443"
|
- 127.0.0.1:4430
|
||||||
|
- 127.0.0.1:4431
|
||||||
|
tls: false
|
||||||
|
account:
|
||||||
|
peerId: 12D3KooWMHuhZgK2skkLrvL51QQTXaXQKYy2QqfvPNBFnzR2ubA1
|
||||||
|
signingKey: 3id6ddLcoNoe9rDgGM88ET8T6TnvHm5GFqFdN6kBzn7Q8d6VUGgjeT59CNWFiaofdeRnHBvX2A5ZacMXvfwaYEFuCbug
|
||||||
|
encryptionKey: JgG4CcCbae1qEpe7mKpBzsHjZhXUmDSNVNX2B1gxFZsJyMX4V6kBQUott9zRWyeXaW1ZmpzuxDXnwSQpAnNurhXyGa9iQaAPqzY9A9VWBPD33Yy1eW7TRuVemzToh8jJQKQKnZNbF8ucTWV9qahusKzyvN8uyhrqoW2tAPfA9S3E3ognCuqbLSW6yjE2rBKayvyS1BVwzjSd6FZK4DDyjfU3pbEVjut3wytGEAn9af6sNMmyCnf2MX5vLovWs9rU8av61wD4z7HTsXyGFx4K75N4Go249Hpe9SKAT6HxhRc3yvj63krPLiQV5yMuH2UeMUXBDekUQyNmBEdn9wrur7mLqB67Bc6tcc2PP8XApBCdWJHvHjN4FktSpaG5vbCqoZbLD1oCbk36q2x9s6XM8pydVqD1J9P3nTbfgMb5pJCTFjNtgKeuKv6wjfJeA9jF1VhcJQisfsahgv9MvZ9M8FJpZTq1zKUhYDCRnZxUkraoMS5yNNVdDzaUckKEDthqik7BMWCWT79vq7uVgMwEvGwGi76gtoMg1159bbPMLZ4bdPVfhH2S9QjPrzQfwZSrzB2YeVPjWpaXDeLDity5H8n1NK2oniAQR6gE71n81neSptsuhV6o6QpQ89AU8y57XmEsou4VEryn8vUxBHhULLxrLNUouxyWamCeFiDjk5cSN6koQsf9BYKSNTPFTrwjTKForDokMhcPdMtFktKwjv7u9UEGcY4MKvNzZZkc77gHiP8bqVtdNNoLpTFUC5SZ9i7bKdHvK12HpSy7yzzPeMXJ9UwhLxkok1g81ngTbN1yxRhvYXyHZFtguCR9kvGojDjka91MTBtk551qDw9eCn2xZT9U8jqzBCjdpvSg3mRWKMPnYAGB7m7u1ye165wyGFvzcHAx3vtXjxAqLUeKYZCjv2m6V9D2Y4qH1TQNddWqH14T1JVMis971UCH9Ddpj6a3387oUnufD1P6HZN2ieJCvptrmbGVvxJYYSvmVf1dkwbtqurDRNWD7TJ7gf6iqSP549C9bxP4GpLt3ygjHmMtcuUzstBuztvunJUnQhfnJxqU6LjRdsFzm53wGWgXNxab7ZvQcPyLwsevn1b98FGPnVpS5iY4LjmqW4ugrC6HgrbsjrXiKzR1yZKhLQkCbLzPoaHb8iB5iBnCr7d4yf5CtfpFRqgoqMFdK5LNZYmDX4HzUKN6A7wC3gGiSRFTLcgGZeSMkB5Pa61CZBU7WCQgFxykycE9HRA7PiQa496GWDCV15teToCpFRsAa6jDmR1MGXPeLRqQgve49VXnQN5FL7c1VuEv5SWjeTuCnMB47DJKBaP7eKJNKgLwETALzSCMF3nRiRgeb15kfoS4BbrJ5yupjrvwmbmvNg1AYFFS5sYNWft7K8v87wQvBakRtGP71Kp8NX77XFtu6xdB7sR6jpfC6qJPyB9akWNXgCrWy9kE4ih42gwAZdUugNZ9YtEsgRM3pwb6qJhkAPyEJtrxrja859PCAgqPSQiPQN33PaMkgQ6HJknu8CrjKRiXAycZ16KLUkHV64TNhEjPTcX1a7rqpD131AYMWX8d7CCdc9Ys7RUb6BwguuNSh8rJK3x4AkMDSUsaE8ynKvpC7RXZpJ9Nxfhd
|
||||||
|
apiServer:
|
||||||
|
port: "8080"
|
||||||
|
nodes:
|
||||||
|
- peerId: 12D3KooWMHuhZgK2skkLrvL51QQTXaXQKYy2QqfvPNBFnzR2ubA1
|
||||||
|
address: 127.0.0.1:4430
|
||||||
|
signingKey: 3id6ddLcoNoe9rDgGM88ET8T6TnvHm5GFqFdN6kBzn7Q8d6VUGgjeT59CNWFiaofdeRnHBvX2A5ZacMXvfwaYEFuCbug
|
||||||
|
encryptionKey: JgG4CcCbae1qEpe7mKpBzsHjZhXUmDSNVNX2B1gxFZsJyMX4V6kBQUott9zRWyeXaW1ZmpzuxDXnwSQpAnNurhXyGa9iQaAPqzY9A9VWBPD33Yy1eW7TRuVemzToh8jJQKQKnZNbF8ucTWV9qahusKzyvN8uyhrqoW2tAPfA9S3E3ognCuqbLSW6yjE2rBKayvyS1BVwzjSd6FZK4DDyjfU3pbEVjut3wytGEAn9af6sNMmyCnf2MX5vLovWs9rU8av61wD4z7HTsXyGFx4K75N4Go249Hpe9SKAT6HxhRc3yvj63krPLiQV5yMuH2UeMUXBDekUQyNmBEdn9wrur7mLqB67Bc6tcc2PP8XApBCdWJHvHjN4FktSpaG5vbCqoZbLD1oCbk36q2x9s6XM8pydVqD1J9P3nTbfgMb5pJCTFjNtgKeuKv6wjfJeA9jF1VhcJQisfsahgv9MvZ9M8FJpZTq1zKUhYDCRnZxUkraoMS5yNNVdDzaUckKEDthqik7BMWCWT79vq7uVgMwEvGwGi76gtoMg1159bbPMLZ4bdPVfhH2S9QjPrzQfwZSrzB2YeVPjWpaXDeLDity5H8n1NK2oniAQR6gE71n81neSptsuhV6o6QpQ89AU8y57XmEsou4VEryn8vUxBHhULLxrLNUouxyWamCeFiDjk5cSN6koQsf9BYKSNTPFTrwjTKForDokMhcPdMtFktKwjv7u9UEGcY4MKvNzZZkc77gHiP8bqVtdNNoLpTFUC5SZ9i7bKdHvK12HpSy7yzzPeMXJ9UwhLxkok1g81ngTbN1yxRhvYXyHZFtguCR9kvGojDjka91MTBtk551qDw9eCn2xZT9U8jqzBCjdpvSg3mRWKMPnYAGB7m7u1ye165wyGFvzcHAx3vtXjxAqLUeKYZCjv2m6V9D2Y4qH1TQNddWqH14T1JVMis971UCH9Ddpj6a3387oUnufD1P6HZN2ieJCvptrmbGVvxJYYSvmVf1dkwbtqurDRNWD7TJ7gf6iqSP549C9bxP4GpLt3ygjHmMtcuUzstBuztvunJUnQhfnJxqU6LjRdsFzm53wGWgXNxab7ZvQcPyLwsevn1b98FGPnVpS5iY4LjmqW4ugrC6HgrbsjrXiKzR1yZKhLQkCbLzPoaHb8iB5iBnCr7d4yf5CtfpFRqgoqMFdK5LNZYmDX4HzUKN6A7wC3gGiSRFTLcgGZeSMkB5Pa61CZBU7WCQgFxykycE9HRA7PiQa496GWDCV15teToCpFRsAa6jDmR1MGXPeLRqQgve49VXnQN5FL7c1VuEv5SWjeTuCnMB47DJKBaP7eKJNKgLwETALzSCMF3nRiRgeb15kfoS4BbrJ5yupjrvwmbmvNg1AYFFS5sYNWft7K8v87wQvBakRtGP71Kp8NX77XFtu6xdB7sR6jpfC6qJPyB9akWNXgCrWy9kE4ih42gwAZdUugNZ9YtEsgRM3pwb6qJhkAPyEJtrxrja859PCAgqPSQiPQN33PaMkgQ6HJknu8CrjKRiXAycZ16KLUkHV64TNhEjPTcX1a7rqpD131AYMWX8d7CCdc9Ys7RUb6BwguuNSh8rJK3x4AkMDSUsaE8ynKvpC7RXZpJ9Nxfhd
|
||||||
|
- peerId: 12D3KooWT3c7Y5zvWhhjSxd5Ve3GKZi6WCsG6JHxcxgXixRFdBbw
|
||||||
|
address: 127.0.0.1:4432
|
||||||
|
signingKey: 3iiLPj6wMUQpPwTBNZcUgkbXub1jumg4AEV9LfMyFHZVc84GLyAjVbVvH6EAGhcNrxRxL82aW4BimhDZCpLsRCqx5vwj
|
||||||
|
encryptionKey: JgG4CcCbae1qEpe7mKXzp7m5hNc56SSyZd9DwUaEStKJrq7RToAC2Vgd3i6hKRwa58zCWeN6Wjc3o6qrdKPEPRvcyEPysamajVo5mdQiUgWAmr97pGEsyjuRjQoC2GY2LvLiEQxEgwFgJxKGMHMiaWMtDfxCDUaDEm4bu5RdMhqRZekAWho6c3WoEeruSr14iX1TrocFNfBkBY7CjEw8kcywXCTNgtvhb2Qiwgj5AxEF4wyw4bzaNA9ctXb1hoHPFVMu6C51pkFY7jUD9zwyH3ukgnAewkGAcPNbKmaTAtMosKRVaAN97mAwXh2VRt1hWmRvVk7r76EjnVKhD4vbsKZc56RVcHTVWRVdhU7FGyPsiE5rSQAz1JQGYzxnZpX7EG77CyrmUGyfueVfRHhwY2oq8A4uQCRaQxSaJHYLowjXSxh8DQ2V6MTqyzti32C27utBYdHzLVCJSGkmdzGwrFcHqsq7nLDxmvJVErPvyReixEe8kFmqopJ3e6LLm8WdYw9K6JYBjXnEfwPzm7Von9sf3dcaGDUHYfttMyeke7fAXJkvPRje69hYVyzdQGAauuojzGkkvQWCSMK1KCMNMznRaPDCNvofrQhYrub24WhmwpKhorufdfW8Cb4T6reBDCtaWVsbuinjtL6F6Sui5aYHJFLJ6e4pPewr1P4EuZYRbMBZwN5KvDLhTGLBuBnaTqUUdF6bj2U22NoRYMogiHiftqKqiexKNDXX1Zg9RQEvxgjuVo6SBW42mVEA8agrLhruRqCmiduJxVrfqLNGeYXHXrcmMEgW7uosJbPXvTcfRvdFWS1ov7oSALvj6vhDQ28Yi9D2ETNdNsfVWAFQuwvPpW7CHQGXTitprVbqH8JYxNZuGygcLmr5efbB22Vzu4ntd1HoraQpG12qeDEUA7tXYUpoYyuSdWwKPjSAMtaQcCSfVrhKQHQuKJargrVrez8vjWuwLfvSucV7ZHe7gjqvYgULdE1ubRCRSd7DuLjEN2Vd6obzV2c3MRet7ZSf4Sp88WM5AuTyW7BjArBc4S3gUQ8rYaiZ8Tu7NCxkEzbFwWRaemZkwfvcsX3XxqjyF37tFSGkEqE5kuBvpZW72675LkDffj7kH1zA8yE6dVujJjWsNYVFJWndUtz5Vy2KCdZAbBgq19q4AtsxWPodU2N3yZXzFAFAzTrxS6V4P7Scpdau1avgRvHLcBQPunA37xaYMy8YMifJwtmRY25mnAQwZAk3eANk7tXwZd58SDnciLNvARJvwKzTQBXcshkwyy52SX8XmXDJsPnRLaHmiYBJ63Yzr5XpZuuAtxb9qrWG2NHCNxfomHokWacV1hjZPPd6ZxT1FuRozB6Qt2NLcyqY7bnTcQJb1jPUaTAGXXCR8WVmmmYo2fDQe8CdBmgyPvbzNTEJUyScBz4RdycB5PZap4SurJCWtHbuMyQbQUB6jJgURDstfXS5Akfe4oruNq9rnYcNtnsDJPtrhXHBqzDizmf1BDxR5FB2RCxzCgeAfg8WQ1Ug9PVAGTzob6ZqCrGXzWXEUniZnf1vjr7QhGKBYXEX9SWDoSMUpP4FreVDTnx15ijRZTV3p8xG5fE9e36TnugRVvTyq7XzmyPBjW2r66f1bior
|
||||||
|
|||||||
22
etc/configs/12D3KooWMHuhZgK2skkLrvL51QQTXaXQKYy2QqfvPNBFnzR2ubA1.yml
Executable file
22
etc/configs/12D3KooWMHuhZgK2skkLrvL51QQTXaXQKYy2QqfvPNBFnzR2ubA1.yml
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
anytype:
|
||||||
|
swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec
|
||||||
|
grpcServer:
|
||||||
|
listenAddrs:
|
||||||
|
- 127.0.0.1:4430
|
||||||
|
- 127.0.0.1:4431
|
||||||
|
tls: false
|
||||||
|
account:
|
||||||
|
peerId: 12D3KooWMHuhZgK2skkLrvL51QQTXaXQKYy2QqfvPNBFnzR2ubA1
|
||||||
|
signingKey: 3id6ddLcoNoe9rDgGM88ET8T6TnvHm5GFqFdN6kBzn7Q8d6VUGgjeT59CNWFiaofdeRnHBvX2A5ZacMXvfwaYEFuCbug
|
||||||
|
encryptionKey: JgG4CcCbae1qEpe7mKpBzsHjZhXUmDSNVNX2B1gxFZsJyMX4V6kBQUott9zRWyeXaW1ZmpzuxDXnwSQpAnNurhXyGa9iQaAPqzY9A9VWBPD33Yy1eW7TRuVemzToh8jJQKQKnZNbF8ucTWV9qahusKzyvN8uyhrqoW2tAPfA9S3E3ognCuqbLSW6yjE2rBKayvyS1BVwzjSd6FZK4DDyjfU3pbEVjut3wytGEAn9af6sNMmyCnf2MX5vLovWs9rU8av61wD4z7HTsXyGFx4K75N4Go249Hpe9SKAT6HxhRc3yvj63krPLiQV5yMuH2UeMUXBDekUQyNmBEdn9wrur7mLqB67Bc6tcc2PP8XApBCdWJHvHjN4FktSpaG5vbCqoZbLD1oCbk36q2x9s6XM8pydVqD1J9P3nTbfgMb5pJCTFjNtgKeuKv6wjfJeA9jF1VhcJQisfsahgv9MvZ9M8FJpZTq1zKUhYDCRnZxUkraoMS5yNNVdDzaUckKEDthqik7BMWCWT79vq7uVgMwEvGwGi76gtoMg1159bbPMLZ4bdPVfhH2S9QjPrzQfwZSrzB2YeVPjWpaXDeLDity5H8n1NK2oniAQR6gE71n81neSptsuhV6o6QpQ89AU8y57XmEsou4VEryn8vUxBHhULLxrLNUouxyWamCeFiDjk5cSN6koQsf9BYKSNTPFTrwjTKForDokMhcPdMtFktKwjv7u9UEGcY4MKvNzZZkc77gHiP8bqVtdNNoLpTFUC5SZ9i7bKdHvK12HpSy7yzzPeMXJ9UwhLxkok1g81ngTbN1yxRhvYXyHZFtguCR9kvGojDjka91MTBtk551qDw9eCn2xZT9U8jqzBCjdpvSg3mRWKMPnYAGB7m7u1ye165wyGFvzcHAx3vtXjxAqLUeKYZCjv2m6V9D2Y4qH1TQNddWqH14T1JVMis971UCH9Ddpj6a3387oUnufD1P6HZN2ieJCvptrmbGVvxJYYSvmVf1dkwbtqurDRNWD7TJ7gf6iqSP549C9bxP4GpLt3ygjHmMtcuUzstBuztvunJUnQhfnJxqU6LjRdsFzm53wGWgXNxab7ZvQcPyLwsevn1b98FGPnVpS5iY4LjmqW4ugrC6HgrbsjrXiKzR1yZKhLQkCbLzPoaHb8iB5iBnCr7d4yf5CtfpFRqgoqMFdK5LNZYmDX4HzUKN6A7wC3gGiSRFTLcgGZeSMkB5Pa61CZBU7WCQgFxykycE9HRA7PiQa496GWDCV15teToCpFRsAa6jDmR1MGXPeLRqQgve49VXnQN5FL7c1VuEv5SWjeTuCnMB47DJKBaP7eKJNKgLwETALzSCMF3nRiRgeb15kfoS4BbrJ5yupjrvwmbmvNg1AYFFS5sYNWft7K8v87wQvBakRtGP71Kp8NX77XFtu6xdB7sR6jpfC6qJPyB9akWNXgCrWy9kE4ih42gwAZdUugNZ9YtEsgRM3pwb6qJhkAPyEJtrxrja859PCAgqPSQiPQN33PaMkgQ6HJknu8CrjKRiXAycZ16KLUkHV64TNhEjPTcX1a7rqpD131AYMWX8d7CCdc9Ys7RUb6BwguuNSh8rJK3x4AkMDSUsaE8ynKvpC7RXZpJ9Nxfhd
|
||||||
|
apiServer:
|
||||||
|
port: "8080"
|
||||||
|
nodes:
|
||||||
|
- peerId: 12D3KooWMHuhZgK2skkLrvL51QQTXaXQKYy2QqfvPNBFnzR2ubA1
|
||||||
|
address: 127.0.0.1:4430
|
||||||
|
signingKey: 3id6ddLcoNoe9rDgGM88ET8T6TnvHm5GFqFdN6kBzn7Q8d6VUGgjeT59CNWFiaofdeRnHBvX2A5ZacMXvfwaYEFuCbug
|
||||||
|
encryptionKey: JgG4CcCbae1qEpe7mKpBzsHjZhXUmDSNVNX2B1gxFZsJyMX4V6kBQUott9zRWyeXaW1ZmpzuxDXnwSQpAnNurhXyGa9iQaAPqzY9A9VWBPD33Yy1eW7TRuVemzToh8jJQKQKnZNbF8ucTWV9qahusKzyvN8uyhrqoW2tAPfA9S3E3ognCuqbLSW6yjE2rBKayvyS1BVwzjSd6FZK4DDyjfU3pbEVjut3wytGEAn9af6sNMmyCnf2MX5vLovWs9rU8av61wD4z7HTsXyGFx4K75N4Go249Hpe9SKAT6HxhRc3yvj63krPLiQV5yMuH2UeMUXBDekUQyNmBEdn9wrur7mLqB67Bc6tcc2PP8XApBCdWJHvHjN4FktSpaG5vbCqoZbLD1oCbk36q2x9s6XM8pydVqD1J9P3nTbfgMb5pJCTFjNtgKeuKv6wjfJeA9jF1VhcJQisfsahgv9MvZ9M8FJpZTq1zKUhYDCRnZxUkraoMS5yNNVdDzaUckKEDthqik7BMWCWT79vq7uVgMwEvGwGi76gtoMg1159bbPMLZ4bdPVfhH2S9QjPrzQfwZSrzB2YeVPjWpaXDeLDity5H8n1NK2oniAQR6gE71n81neSptsuhV6o6QpQ89AU8y57XmEsou4VEryn8vUxBHhULLxrLNUouxyWamCeFiDjk5cSN6koQsf9BYKSNTPFTrwjTKForDokMhcPdMtFktKwjv7u9UEGcY4MKvNzZZkc77gHiP8bqVtdNNoLpTFUC5SZ9i7bKdHvK12HpSy7yzzPeMXJ9UwhLxkok1g81ngTbN1yxRhvYXyHZFtguCR9kvGojDjka91MTBtk551qDw9eCn2xZT9U8jqzBCjdpvSg3mRWKMPnYAGB7m7u1ye165wyGFvzcHAx3vtXjxAqLUeKYZCjv2m6V9D2Y4qH1TQNddWqH14T1JVMis971UCH9Ddpj6a3387oUnufD1P6HZN2ieJCvptrmbGVvxJYYSvmVf1dkwbtqurDRNWD7TJ7gf6iqSP549C9bxP4GpLt3ygjHmMtcuUzstBuztvunJUnQhfnJxqU6LjRdsFzm53wGWgXNxab7ZvQcPyLwsevn1b98FGPnVpS5iY4LjmqW4ugrC6HgrbsjrXiKzR1yZKhLQkCbLzPoaHb8iB5iBnCr7d4yf5CtfpFRqgoqMFdK5LNZYmDX4HzUKN6A7wC3gGiSRFTLcgGZeSMkB5Pa61CZBU7WCQgFxykycE9HRA7PiQa496GWDCV15teToCpFRsAa6jDmR1MGXPeLRqQgve49VXnQN5FL7c1VuEv5SWjeTuCnMB47DJKBaP7eKJNKgLwETALzSCMF3nRiRgeb15kfoS4BbrJ5yupjrvwmbmvNg1AYFFS5sYNWft7K8v87wQvBakRtGP71Kp8NX77XFtu6xdB7sR6jpfC6qJPyB9akWNXgCrWy9kE4ih42gwAZdUugNZ9YtEsgRM3pwb6qJhkAPyEJtrxrja859PCAgqPSQiPQN33PaMkgQ6HJknu8CrjKRiXAycZ16KLUkHV64TNhEjPTcX1a7rqpD131AYMWX8d7CCdc9Ys7RUb6BwguuNSh8rJK3x4AkMDSUsaE8ynKvpC7RXZpJ9Nxfhd
|
||||||
|
- peerId: 12D3KooWT3c7Y5zvWhhjSxd5Ve3GKZi6WCsG6JHxcxgXixRFdBbw
|
||||||
|
address: 127.0.0.1:4432
|
||||||
|
signingKey: 3iiLPj6wMUQpPwTBNZcUgkbXub1jumg4AEV9LfMyFHZVc84GLyAjVbVvH6EAGhcNrxRxL82aW4BimhDZCpLsRCqx5vwj
|
||||||
|
encryptionKey: JgG4CcCbae1qEpe7mKXzp7m5hNc56SSyZd9DwUaEStKJrq7RToAC2Vgd3i6hKRwa58zCWeN6Wjc3o6qrdKPEPRvcyEPysamajVo5mdQiUgWAmr97pGEsyjuRjQoC2GY2LvLiEQxEgwFgJxKGMHMiaWMtDfxCDUaDEm4bu5RdMhqRZekAWho6c3WoEeruSr14iX1TrocFNfBkBY7CjEw8kcywXCTNgtvhb2Qiwgj5AxEF4wyw4bzaNA9ctXb1hoHPFVMu6C51pkFY7jUD9zwyH3ukgnAewkGAcPNbKmaTAtMosKRVaAN97mAwXh2VRt1hWmRvVk7r76EjnVKhD4vbsKZc56RVcHTVWRVdhU7FGyPsiE5rSQAz1JQGYzxnZpX7EG77CyrmUGyfueVfRHhwY2oq8A4uQCRaQxSaJHYLowjXSxh8DQ2V6MTqyzti32C27utBYdHzLVCJSGkmdzGwrFcHqsq7nLDxmvJVErPvyReixEe8kFmqopJ3e6LLm8WdYw9K6JYBjXnEfwPzm7Von9sf3dcaGDUHYfttMyeke7fAXJkvPRje69hYVyzdQGAauuojzGkkvQWCSMK1KCMNMznRaPDCNvofrQhYrub24WhmwpKhorufdfW8Cb4T6reBDCtaWVsbuinjtL6F6Sui5aYHJFLJ6e4pPewr1P4EuZYRbMBZwN5KvDLhTGLBuBnaTqUUdF6bj2U22NoRYMogiHiftqKqiexKNDXX1Zg9RQEvxgjuVo6SBW42mVEA8agrLhruRqCmiduJxVrfqLNGeYXHXrcmMEgW7uosJbPXvTcfRvdFWS1ov7oSALvj6vhDQ28Yi9D2ETNdNsfVWAFQuwvPpW7CHQGXTitprVbqH8JYxNZuGygcLmr5efbB22Vzu4ntd1HoraQpG12qeDEUA7tXYUpoYyuSdWwKPjSAMtaQcCSfVrhKQHQuKJargrVrez8vjWuwLfvSucV7ZHe7gjqvYgULdE1ubRCRSd7DuLjEN2Vd6obzV2c3MRet7ZSf4Sp88WM5AuTyW7BjArBc4S3gUQ8rYaiZ8Tu7NCxkEzbFwWRaemZkwfvcsX3XxqjyF37tFSGkEqE5kuBvpZW72675LkDffj7kH1zA8yE6dVujJjWsNYVFJWndUtz5Vy2KCdZAbBgq19q4AtsxWPodU2N3yZXzFAFAzTrxS6V4P7Scpdau1avgRvHLcBQPunA37xaYMy8YMifJwtmRY25mnAQwZAk3eANk7tXwZd58SDnciLNvARJvwKzTQBXcshkwyy52SX8XmXDJsPnRLaHmiYBJ63Yzr5XpZuuAtxb9qrWG2NHCNxfomHokWacV1hjZPPd6ZxT1FuRozB6Qt2NLcyqY7bnTcQJb1jPUaTAGXXCR8WVmmmYo2fDQe8CdBmgyPvbzNTEJUyScBz4RdycB5PZap4SurJCWtHbuMyQbQUB6jJgURDstfXS5Akfe4oruNq9rnYcNtnsDJPtrhXHBqzDizmf1BDxR5FB2RCxzCgeAfg8WQ1Ug9PVAGTzob6ZqCrGXzWXEUniZnf1vjr7QhGKBYXEX9SWDoSMUpP4FreVDTnx15ijRZTV3p8xG5fE9e36TnugRVvTyq7XzmyPBjW2r66f1bior
|
||||||
22
etc/configs/12D3KooWT3c7Y5zvWhhjSxd5Ve3GKZi6WCsG6JHxcxgXixRFdBbw.yml
Executable file
22
etc/configs/12D3KooWT3c7Y5zvWhhjSxd5Ve3GKZi6WCsG6JHxcxgXixRFdBbw.yml
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
anytype:
|
||||||
|
swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec
|
||||||
|
grpcServer:
|
||||||
|
listenAddrs:
|
||||||
|
- 127.0.0.1:4432
|
||||||
|
- 127.0.0.1:4433
|
||||||
|
tls: false
|
||||||
|
account:
|
||||||
|
peerId: 12D3KooWT3c7Y5zvWhhjSxd5Ve3GKZi6WCsG6JHxcxgXixRFdBbw
|
||||||
|
signingKey: 3iiLPj6wMUQpPwTBNZcUgkbXub1jumg4AEV9LfMyFHZVc84GLyAjVbVvH6EAGhcNrxRxL82aW4BimhDZCpLsRCqx5vwj
|
||||||
|
encryptionKey: JgG4CcCbae1qEpe7mKXzp7m5hNc56SSyZd9DwUaEStKJrq7RToAC2Vgd3i6hKRwa58zCWeN6Wjc3o6qrdKPEPRvcyEPysamajVo5mdQiUgWAmr97pGEsyjuRjQoC2GY2LvLiEQxEgwFgJxKGMHMiaWMtDfxCDUaDEm4bu5RdMhqRZekAWho6c3WoEeruSr14iX1TrocFNfBkBY7CjEw8kcywXCTNgtvhb2Qiwgj5AxEF4wyw4bzaNA9ctXb1hoHPFVMu6C51pkFY7jUD9zwyH3ukgnAewkGAcPNbKmaTAtMosKRVaAN97mAwXh2VRt1hWmRvVk7r76EjnVKhD4vbsKZc56RVcHTVWRVdhU7FGyPsiE5rSQAz1JQGYzxnZpX7EG77CyrmUGyfueVfRHhwY2oq8A4uQCRaQxSaJHYLowjXSxh8DQ2V6MTqyzti32C27utBYdHzLVCJSGkmdzGwrFcHqsq7nLDxmvJVErPvyReixEe8kFmqopJ3e6LLm8WdYw9K6JYBjXnEfwPzm7Von9sf3dcaGDUHYfttMyeke7fAXJkvPRje69hYVyzdQGAauuojzGkkvQWCSMK1KCMNMznRaPDCNvofrQhYrub24WhmwpKhorufdfW8Cb4T6reBDCtaWVsbuinjtL6F6Sui5aYHJFLJ6e4pPewr1P4EuZYRbMBZwN5KvDLhTGLBuBnaTqUUdF6bj2U22NoRYMogiHiftqKqiexKNDXX1Zg9RQEvxgjuVo6SBW42mVEA8agrLhruRqCmiduJxVrfqLNGeYXHXrcmMEgW7uosJbPXvTcfRvdFWS1ov7oSALvj6vhDQ28Yi9D2ETNdNsfVWAFQuwvPpW7CHQGXTitprVbqH8JYxNZuGygcLmr5efbB22Vzu4ntd1HoraQpG12qeDEUA7tXYUpoYyuSdWwKPjSAMtaQcCSfVrhKQHQuKJargrVrez8vjWuwLfvSucV7ZHe7gjqvYgULdE1ubRCRSd7DuLjEN2Vd6obzV2c3MRet7ZSf4Sp88WM5AuTyW7BjArBc4S3gUQ8rYaiZ8Tu7NCxkEzbFwWRaemZkwfvcsX3XxqjyF37tFSGkEqE5kuBvpZW72675LkDffj7kH1zA8yE6dVujJjWsNYVFJWndUtz5Vy2KCdZAbBgq19q4AtsxWPodU2N3yZXzFAFAzTrxS6V4P7Scpdau1avgRvHLcBQPunA37xaYMy8YMifJwtmRY25mnAQwZAk3eANk7tXwZd58SDnciLNvARJvwKzTQBXcshkwyy52SX8XmXDJsPnRLaHmiYBJ63Yzr5XpZuuAtxb9qrWG2NHCNxfomHokWacV1hjZPPd6ZxT1FuRozB6Qt2NLcyqY7bnTcQJb1jPUaTAGXXCR8WVmmmYo2fDQe8CdBmgyPvbzNTEJUyScBz4RdycB5PZap4SurJCWtHbuMyQbQUB6jJgURDstfXS5Akfe4oruNq9rnYcNtnsDJPtrhXHBqzDizmf1BDxR5FB2RCxzCgeAfg8WQ1Ug9PVAGTzob6ZqCrGXzWXEUniZnf1vjr7QhGKBYXEX9SWDoSMUpP4FreVDTnx15ijRZTV3p8xG5fE9e36TnugRVvTyq7XzmyPBjW2r66f1bior
|
||||||
|
apiServer:
|
||||||
|
port: "8081"
|
||||||
|
nodes:
|
||||||
|
- peerId: 12D3KooWMHuhZgK2skkLrvL51QQTXaXQKYy2QqfvPNBFnzR2ubA1
|
||||||
|
address: 127.0.0.1:4430
|
||||||
|
signingKey: 3id6ddLcoNoe9rDgGM88ET8T6TnvHm5GFqFdN6kBzn7Q8d6VUGgjeT59CNWFiaofdeRnHBvX2A5ZacMXvfwaYEFuCbug
|
||||||
|
encryptionKey: JgG4CcCbae1qEpe7mKpBzsHjZhXUmDSNVNX2B1gxFZsJyMX4V6kBQUott9zRWyeXaW1ZmpzuxDXnwSQpAnNurhXyGa9iQaAPqzY9A9VWBPD33Yy1eW7TRuVemzToh8jJQKQKnZNbF8ucTWV9qahusKzyvN8uyhrqoW2tAPfA9S3E3ognCuqbLSW6yjE2rBKayvyS1BVwzjSd6FZK4DDyjfU3pbEVjut3wytGEAn9af6sNMmyCnf2MX5vLovWs9rU8av61wD4z7HTsXyGFx4K75N4Go249Hpe9SKAT6HxhRc3yvj63krPLiQV5yMuH2UeMUXBDekUQyNmBEdn9wrur7mLqB67Bc6tcc2PP8XApBCdWJHvHjN4FktSpaG5vbCqoZbLD1oCbk36q2x9s6XM8pydVqD1J9P3nTbfgMb5pJCTFjNtgKeuKv6wjfJeA9jF1VhcJQisfsahgv9MvZ9M8FJpZTq1zKUhYDCRnZxUkraoMS5yNNVdDzaUckKEDthqik7BMWCWT79vq7uVgMwEvGwGi76gtoMg1159bbPMLZ4bdPVfhH2S9QjPrzQfwZSrzB2YeVPjWpaXDeLDity5H8n1NK2oniAQR6gE71n81neSptsuhV6o6QpQ89AU8y57XmEsou4VEryn8vUxBHhULLxrLNUouxyWamCeFiDjk5cSN6koQsf9BYKSNTPFTrwjTKForDokMhcPdMtFktKwjv7u9UEGcY4MKvNzZZkc77gHiP8bqVtdNNoLpTFUC5SZ9i7bKdHvK12HpSy7yzzPeMXJ9UwhLxkok1g81ngTbN1yxRhvYXyHZFtguCR9kvGojDjka91MTBtk551qDw9eCn2xZT9U8jqzBCjdpvSg3mRWKMPnYAGB7m7u1ye165wyGFvzcHAx3vtXjxAqLUeKYZCjv2m6V9D2Y4qH1TQNddWqH14T1JVMis971UCH9Ddpj6a3387oUnufD1P6HZN2ieJCvptrmbGVvxJYYSvmVf1dkwbtqurDRNWD7TJ7gf6iqSP549C9bxP4GpLt3ygjHmMtcuUzstBuztvunJUnQhfnJxqU6LjRdsFzm53wGWgXNxab7ZvQcPyLwsevn1b98FGPnVpS5iY4LjmqW4ugrC6HgrbsjrXiKzR1yZKhLQkCbLzPoaHb8iB5iBnCr7d4yf5CtfpFRqgoqMFdK5LNZYmDX4HzUKN6A7wC3gGiSRFTLcgGZeSMkB5Pa61CZBU7WCQgFxykycE9HRA7PiQa496GWDCV15teToCpFRsAa6jDmR1MGXPeLRqQgve49VXnQN5FL7c1VuEv5SWjeTuCnMB47DJKBaP7eKJNKgLwETALzSCMF3nRiRgeb15kfoS4BbrJ5yupjrvwmbmvNg1AYFFS5sYNWft7K8v87wQvBakRtGP71Kp8NX77XFtu6xdB7sR6jpfC6qJPyB9akWNXgCrWy9kE4ih42gwAZdUugNZ9YtEsgRM3pwb6qJhkAPyEJtrxrja859PCAgqPSQiPQN33PaMkgQ6HJknu8CrjKRiXAycZ16KLUkHV64TNhEjPTcX1a7rqpD131AYMWX8d7CCdc9Ys7RUb6BwguuNSh8rJK3x4AkMDSUsaE8ynKvpC7RXZpJ9Nxfhd
|
||||||
|
- peerId: 12D3KooWT3c7Y5zvWhhjSxd5Ve3GKZi6WCsG6JHxcxgXixRFdBbw
|
||||||
|
address: 127.0.0.1:4432
|
||||||
|
signingKey: 3iiLPj6wMUQpPwTBNZcUgkbXub1jumg4AEV9LfMyFHZVc84GLyAjVbVvH6EAGhcNrxRxL82aW4BimhDZCpLsRCqx5vwj
|
||||||
|
encryptionKey: JgG4CcCbae1qEpe7mKXzp7m5hNc56SSyZd9DwUaEStKJrq7RToAC2Vgd3i6hKRwa58zCWeN6Wjc3o6qrdKPEPRvcyEPysamajVo5mdQiUgWAmr97pGEsyjuRjQoC2GY2LvLiEQxEgwFgJxKGMHMiaWMtDfxCDUaDEm4bu5RdMhqRZekAWho6c3WoEeruSr14iX1TrocFNfBkBY7CjEw8kcywXCTNgtvhb2Qiwgj5AxEF4wyw4bzaNA9ctXb1hoHPFVMu6C51pkFY7jUD9zwyH3ukgnAewkGAcPNbKmaTAtMosKRVaAN97mAwXh2VRt1hWmRvVk7r76EjnVKhD4vbsKZc56RVcHTVWRVdhU7FGyPsiE5rSQAz1JQGYzxnZpX7EG77CyrmUGyfueVfRHhwY2oq8A4uQCRaQxSaJHYLowjXSxh8DQ2V6MTqyzti32C27utBYdHzLVCJSGkmdzGwrFcHqsq7nLDxmvJVErPvyReixEe8kFmqopJ3e6LLm8WdYw9K6JYBjXnEfwPzm7Von9sf3dcaGDUHYfttMyeke7fAXJkvPRje69hYVyzdQGAauuojzGkkvQWCSMK1KCMNMznRaPDCNvofrQhYrub24WhmwpKhorufdfW8Cb4T6reBDCtaWVsbuinjtL6F6Sui5aYHJFLJ6e4pPewr1P4EuZYRbMBZwN5KvDLhTGLBuBnaTqUUdF6bj2U22NoRYMogiHiftqKqiexKNDXX1Zg9RQEvxgjuVo6SBW42mVEA8agrLhruRqCmiduJxVrfqLNGeYXHXrcmMEgW7uosJbPXvTcfRvdFWS1ov7oSALvj6vhDQ28Yi9D2ETNdNsfVWAFQuwvPpW7CHQGXTitprVbqH8JYxNZuGygcLmr5efbB22Vzu4ntd1HoraQpG12qeDEUA7tXYUpoYyuSdWwKPjSAMtaQcCSfVrhKQHQuKJargrVrez8vjWuwLfvSucV7ZHe7gjqvYgULdE1ubRCRSd7DuLjEN2Vd6obzV2c3MRet7ZSf4Sp88WM5AuTyW7BjArBc4S3gUQ8rYaiZ8Tu7NCxkEzbFwWRaemZkwfvcsX3XxqjyF37tFSGkEqE5kuBvpZW72675LkDffj7kH1zA8yE6dVujJjWsNYVFJWndUtz5Vy2KCdZAbBgq19q4AtsxWPodU2N3yZXzFAFAzTrxS6V4P7Scpdau1avgRvHLcBQPunA37xaYMy8YMifJwtmRY25mnAQwZAk3eANk7tXwZd58SDnciLNvARJvwKzTQBXcshkwyy52SX8XmXDJsPnRLaHmiYBJ63Yzr5XpZuuAtxb9qrWG2NHCNxfomHokWacV1hjZPPd6ZxT1FuRozB6Qt2NLcyqY7bnTcQJb1jPUaTAGXXCR8WVmmmYo2fDQe8CdBmgyPvbzNTEJUyScBz4RdycB5PZap4SurJCWtHbuMyQbQUB6jJgURDstfXS5Akfe4oruNq9rnYcNtnsDJPtrhXHBqzDizmf1BDxR5FB2RCxzCgeAfg8WQ1Ug9PVAGTzob6ZqCrGXzWXEUniZnf1vjr7QhGKBYXEX9SWDoSMUpP4FreVDTnx15ijRZTV3p8xG5fE9e36TnugRVvTyq7XzmyPBjW2r66f1bior
|
||||||
29
go.mod
29
go.mod
@ -4,34 +4,51 @@ go 1.18
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab
|
github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab
|
||||||
|
github.com/cheggaaa/mb v1.0.3
|
||||||
github.com/goccy/go-graphviz v0.0.9
|
github.com/goccy/go-graphviz v0.0.9
|
||||||
github.com/gogo/protobuf v1.3.2
|
github.com/gogo/protobuf v1.3.2
|
||||||
github.com/ipfs/go-cid v0.0.7
|
github.com/ipfs/go-cid v0.1.0
|
||||||
|
github.com/libp2p/go-libp2p v0.20.3
|
||||||
|
github.com/libp2p/go-libp2p-core v0.16.1
|
||||||
github.com/mr-tron/base58 v1.2.0
|
github.com/mr-tron/base58 v1.2.0
|
||||||
github.com/multiformats/go-multibase v0.0.3
|
github.com/multiformats/go-multibase v0.0.3
|
||||||
github.com/multiformats/go-multihash v0.0.15
|
github.com/multiformats/go-multihash v0.1.0
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
go.uber.org/zap v1.21.0
|
go.uber.org/zap v1.21.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
storj.io/drpc v0.0.32
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/btcsuite/btcd v0.22.1 // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.1.3 // indirect
|
||||||
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
|
||||||
github.com/fogleman/gg v1.3.0 // indirect
|
github.com/fogleman/gg v1.3.0 // indirect
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.0.4 // indirect
|
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
||||||
|
github.com/libp2p/go-buffer-pool v0.0.2 // indirect
|
||||||
|
github.com/libp2p/go-openssl v0.0.7 // indirect
|
||||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
|
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
|
||||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||||
github.com/multiformats/go-base32 v0.0.3 // indirect
|
github.com/multiformats/go-base32 v0.0.3 // indirect
|
||||||
github.com/multiformats/go-base36 v0.1.0 // indirect
|
github.com/multiformats/go-base36 v0.1.0 // indirect
|
||||||
|
github.com/multiformats/go-multiaddr v0.5.0 // indirect
|
||||||
|
github.com/multiformats/go-multicodec v0.4.1 // indirect
|
||||||
github.com/multiformats/go-varint v0.0.6 // indirect
|
github.com/multiformats/go-varint v0.0.6 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
|
github.com/zeebo/errs v1.2.2 // indirect
|
||||||
go.uber.org/atomic v1.9.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
go.uber.org/multierr v1.8.0 // indirect
|
go.uber.org/multierr v1.8.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
|
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
|
||||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
|
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
|
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||||
gopkg.in/yaml.v2 v2.3.0 // indirect
|
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
lukechampine.com/blake3 v1.1.6 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
61
go.sum
61
go.sum
@ -1,12 +1,24 @@
|
|||||||
github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab h1:+cdNqtOJWjvepyhxy23G7z7vmpYCoC65AP0nqi1f53s=
|
github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab h1:+cdNqtOJWjvepyhxy23G7z7vmpYCoC65AP0nqi1f53s=
|
||||||
github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs=
|
github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs=
|
||||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
|
||||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
|
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||||
|
github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c=
|
||||||
|
github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.1.3 h1:xM/n3yIhHAhHy04z4i43C8p4ehixJZMsnrVJkgl+MTE=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
|
||||||
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
|
||||||
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
|
||||||
|
github.com/cheggaaa/mb v1.0.3 h1:03ksWum+6kHclB+kjwKMaBtgl5gtNYUwNpxsHQciKe8=
|
||||||
|
github.com/cheggaaa/mb v1.0.3/go.mod h1:NUl0GBtFLlfg2o6iZwxzcG7Lslc2wV/ADTFbLXtVPE4=
|
||||||
github.com/corona10/goimagehash v1.0.2 h1:pUfB0LnsJASMPGEZLj7tGY251vF+qLGqOgEP4rUs6kA=
|
github.com/corona10/goimagehash v1.0.2 h1:pUfB0LnsJASMPGEZLj7tGY251vF+qLGqOgEP4rUs6kA=
|
||||||
github.com/corona10/goimagehash v1.0.2/go.mod h1:/l9umBhvcHQXVtQO1V6Gp1yD20STawkhRnnX0D1bvVI=
|
github.com/corona10/goimagehash v1.0.2/go.mod h1:/l9umBhvcHQXVtQO1V6Gp1yD20STawkhRnnX0D1bvVI=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
|
||||||
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
||||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||||
github.com/goccy/go-graphviz v0.0.9 h1:s/FMMJ1Joj6La3S5ApO3Jk2cwM4LpXECC2muFx3IPQQ=
|
github.com/goccy/go-graphviz v0.0.9 h1:s/FMMJ1Joj6La3S5ApO3Jk2cwM4LpXECC2muFx3IPQQ=
|
||||||
@ -15,18 +27,28 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
|||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||||
github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY=
|
|
||||||
github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
|
github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
|
||||||
|
github.com/ipfs/go-cid v0.1.0 h1:YN33LQulcRHjfom/i25yoOZR4Telp1Hr/2RU3d0PnC0=
|
||||||
|
github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
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/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw=
|
|
||||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs=
|
||||||
|
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
|
||||||
|
github.com/libp2p/go-libp2p v0.20.3 h1:tjjDNfp7FqdI/7v1rXtB/BtELaPlAThL2uzlj18kcrw=
|
||||||
|
github.com/libp2p/go-libp2p v0.20.3/go.mod h1:I+vndVanE/p/SjFbnA+BEmmfAUEpWxrdXZeyQ1Dus5c=
|
||||||
|
github.com/libp2p/go-libp2p-core v0.16.1 h1:bWoiEBqVkpJ13hbv/f69tHODp86t6mvc4fBN4DkK73M=
|
||||||
|
github.com/libp2p/go-libp2p-core v0.16.1/go.mod h1:O3i/7y+LqUb0N+qhzXjBjjpchgptWAVMG1Voegk7b4c=
|
||||||
|
github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw=
|
||||||
|
github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
|
||||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
|
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
|
||||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
|
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
|
||||||
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||||
@ -40,11 +62,17 @@ github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp
|
|||||||
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
|
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
|
||||||
github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
|
github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
|
||||||
github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
|
github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
|
||||||
|
github.com/multiformats/go-multiaddr v0.5.0 h1:i/JuOoVg4szYQ4YEzDGtb2h0o8M7CG/Yq6cGlcjWZpM=
|
||||||
|
github.com/multiformats/go-multiaddr v0.5.0/go.mod h1:3KAxNkUqLTJ20AAwN4XVX4kZar+bR+gh4zgbfr3SNug=
|
||||||
github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk=
|
github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk=
|
||||||
github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
|
github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
|
||||||
|
github.com/multiformats/go-multicodec v0.4.1 h1:BSJbf+zpghcZMZrwTYBGwy0CPcVZGWiC72Cp8bBd4R4=
|
||||||
|
github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ=
|
||||||
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
|
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
|
||||||
github.com/multiformats/go-multihash v0.0.15 h1:hWOPdrNqDjwHDx82vsYGSDZNyktOJJ2dzZJzFkOV1jM=
|
github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
|
||||||
github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg=
|
github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg=
|
||||||
|
github.com/multiformats/go-multihash v0.1.0 h1:CgAgwqk3//SVEw3T+6DqI4mWMyRuDwZtOWcJT0q9+EA=
|
||||||
|
github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84=
|
||||||
github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||||
github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY=
|
github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY=
|
||||||
github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||||
@ -55,6 +83,9 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=
|
||||||
|
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
@ -63,6 +94,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
|
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
|
||||||
|
github.com/zeebo/errs v1.2.2 h1:5NFypMTuSdoySVTqlNs1dEoU21QVamMQJxW/Fii5O7g=
|
||||||
|
github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
@ -79,8 +113,9 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
|
||||||
|
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg=
|
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg=
|
||||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
@ -100,13 +135,15 @@ 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-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
|
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc=
|
||||||
|
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -125,10 +162,16 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
|||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
|
||||||
|
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c=
|
||||||
|
lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
|
||||||
|
storj.io/drpc v0.0.32 h1:5p5ZwsK/VOgapaCu+oxaPVwO6UwIs+iwdMiD50+R4PI=
|
||||||
|
storj.io/drpc v0.0.32/go.mod h1:6rcOyR/QQkSTX/9L5ZGtlZaE2PtXTTZl8d+ulSeeYEg=
|
||||||
|
|||||||
@ -50,7 +50,67 @@ func (x ACLChangeUserPermissions) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ACLChangeUserPermissions) EnumDescriptor() ([]byte, []int) {
|
func (ACLChangeUserPermissions) EnumDescriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 0}
|
return fileDescriptor_37a022c841a51877, []int{1, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
type RawChange struct {
|
||||||
|
Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"`
|
||||||
|
Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
|
||||||
|
Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *RawChange) Reset() { *m = RawChange{} }
|
||||||
|
func (m *RawChange) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*RawChange) ProtoMessage() {}
|
||||||
|
func (*RawChange) Descriptor() ([]byte, []int) {
|
||||||
|
return fileDescriptor_37a022c841a51877, []int{0}
|
||||||
|
}
|
||||||
|
func (m *RawChange) XXX_Unmarshal(b []byte) error {
|
||||||
|
return m.Unmarshal(b)
|
||||||
|
}
|
||||||
|
func (m *RawChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
|
if deterministic {
|
||||||
|
return xxx_messageInfo_RawChange.Marshal(b, m, deterministic)
|
||||||
|
} else {
|
||||||
|
b = b[:cap(b)]
|
||||||
|
n, err := m.MarshalToSizedBuffer(b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return b[:n], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (m *RawChange) XXX_Merge(src proto.Message) {
|
||||||
|
xxx_messageInfo_RawChange.Merge(m, src)
|
||||||
|
}
|
||||||
|
func (m *RawChange) XXX_Size() int {
|
||||||
|
return m.Size()
|
||||||
|
}
|
||||||
|
func (m *RawChange) XXX_DiscardUnknown() {
|
||||||
|
xxx_messageInfo_RawChange.DiscardUnknown(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
var xxx_messageInfo_RawChange proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *RawChange) GetPayload() []byte {
|
||||||
|
if m != nil {
|
||||||
|
return m.Payload
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *RawChange) GetSignature() []byte {
|
||||||
|
if m != nil {
|
||||||
|
return m.Signature
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *RawChange) GetId() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Id
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// the element of change tree used to store and internal apply smartBlock history
|
// the element of change tree used to store and internal apply smartBlock history
|
||||||
@ -70,7 +130,7 @@ func (m *ACLChange) Reset() { *m = ACLChange{} }
|
|||||||
func (m *ACLChange) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChange) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChange) ProtoMessage() {}
|
func (*ACLChange) ProtoMessage() {}
|
||||||
func (*ACLChange) Descriptor() ([]byte, []int) {
|
func (*ACLChange) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0}
|
return fileDescriptor_37a022c841a51877, []int{1}
|
||||||
}
|
}
|
||||||
func (m *ACLChange) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChange) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -170,7 +230,7 @@ func (m *ACLChangeACLContentValue) Reset() { *m = ACLChangeACLContentVal
|
|||||||
func (m *ACLChangeACLContentValue) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeACLContentValue) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeACLContentValue) ProtoMessage() {}
|
func (*ACLChangeACLContentValue) ProtoMessage() {}
|
||||||
func (*ACLChangeACLContentValue) Descriptor() ([]byte, []int) {
|
func (*ACLChangeACLContentValue) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 0}
|
return fileDescriptor_37a022c841a51877, []int{1, 0}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeACLContentValue) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeACLContentValue) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -301,7 +361,7 @@ func (m *ACLChangeACLData) Reset() { *m = ACLChangeACLData{} }
|
|||||||
func (m *ACLChangeACLData) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeACLData) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeACLData) ProtoMessage() {}
|
func (*ACLChangeACLData) ProtoMessage() {}
|
||||||
func (*ACLChangeACLData) Descriptor() ([]byte, []int) {
|
func (*ACLChangeACLData) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 1}
|
return fileDescriptor_37a022c841a51877, []int{1, 1}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeACLData) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeACLData) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -353,7 +413,7 @@ func (m *ACLChangeACLSnapshot) Reset() { *m = ACLChangeACLSnapshot{} }
|
|||||||
func (m *ACLChangeACLSnapshot) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeACLSnapshot) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeACLSnapshot) ProtoMessage() {}
|
func (*ACLChangeACLSnapshot) ProtoMessage() {}
|
||||||
func (*ACLChangeACLSnapshot) Descriptor() ([]byte, []int) {
|
func (*ACLChangeACLSnapshot) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 2}
|
return fileDescriptor_37a022c841a51877, []int{1, 2}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeACLSnapshot) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeACLSnapshot) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -399,7 +459,7 @@ func (m *ACLChangeACLState) Reset() { *m = ACLChangeACLState{} }
|
|||||||
func (m *ACLChangeACLState) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeACLState) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeACLState) ProtoMessage() {}
|
func (*ACLChangeACLState) ProtoMessage() {}
|
||||||
func (*ACLChangeACLState) Descriptor() ([]byte, []int) {
|
func (*ACLChangeACLState) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 3}
|
return fileDescriptor_37a022c841a51877, []int{1, 3}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeACLState) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeACLState) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -453,7 +513,7 @@ type ACLChangeUserState struct {
|
|||||||
Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
|
Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
|
||||||
EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"`
|
EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"`
|
||||||
EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"`
|
EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"`
|
||||||
Permissions ACLChangeUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=anytype.ACLChangeUserPermissions" json:"permissions,omitempty"`
|
Permissions ACLChangeUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=acl.ACLChangeUserPermissions" json:"permissions,omitempty"`
|
||||||
IsConfirmed bool `protobuf:"varint,5,opt,name=IsConfirmed,proto3" json:"IsConfirmed,omitempty"`
|
IsConfirmed bool `protobuf:"varint,5,opt,name=IsConfirmed,proto3" json:"IsConfirmed,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +521,7 @@ func (m *ACLChangeUserState) Reset() { *m = ACLChangeUserState{} }
|
|||||||
func (m *ACLChangeUserState) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeUserState) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeUserState) ProtoMessage() {}
|
func (*ACLChangeUserState) ProtoMessage() {}
|
||||||
func (*ACLChangeUserState) Descriptor() ([]byte, []int) {
|
func (*ACLChangeUserState) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 4}
|
return fileDescriptor_37a022c841a51877, []int{1, 4}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeUserState) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeUserState) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -530,14 +590,14 @@ type ACLChangeUserAdd struct {
|
|||||||
Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
|
Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
|
||||||
EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"`
|
EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"`
|
||||||
EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"`
|
EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"`
|
||||||
Permissions ACLChangeUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=anytype.ACLChangeUserPermissions" json:"permissions,omitempty"`
|
Permissions ACLChangeUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=acl.ACLChangeUserPermissions" json:"permissions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ACLChangeUserAdd) Reset() { *m = ACLChangeUserAdd{} }
|
func (m *ACLChangeUserAdd) Reset() { *m = ACLChangeUserAdd{} }
|
||||||
func (m *ACLChangeUserAdd) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeUserAdd) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeUserAdd) ProtoMessage() {}
|
func (*ACLChangeUserAdd) ProtoMessage() {}
|
||||||
func (*ACLChangeUserAdd) Descriptor() ([]byte, []int) {
|
func (*ACLChangeUserAdd) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 5}
|
return fileDescriptor_37a022c841a51877, []int{1, 5}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeUserAdd) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeUserAdd) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -604,7 +664,7 @@ func (m *ACLChangeUserConfirm) Reset() { *m = ACLChangeUserConfirm{} }
|
|||||||
func (m *ACLChangeUserConfirm) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeUserConfirm) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeUserConfirm) ProtoMessage() {}
|
func (*ACLChangeUserConfirm) ProtoMessage() {}
|
||||||
func (*ACLChangeUserConfirm) Descriptor() ([]byte, []int) {
|
func (*ACLChangeUserConfirm) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 6}
|
return fileDescriptor_37a022c841a51877, []int{1, 6}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeUserConfirm) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeUserConfirm) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -651,7 +711,7 @@ type ACLChangeUserInvite struct {
|
|||||||
AcceptPublicKey []byte `protobuf:"bytes,1,opt,name=acceptPublicKey,proto3" json:"acceptPublicKey,omitempty"`
|
AcceptPublicKey []byte `protobuf:"bytes,1,opt,name=acceptPublicKey,proto3" json:"acceptPublicKey,omitempty"`
|
||||||
EncryptPublicKey []byte `protobuf:"bytes,2,opt,name=encryptPublicKey,proto3" json:"encryptPublicKey,omitempty"`
|
EncryptPublicKey []byte `protobuf:"bytes,2,opt,name=encryptPublicKey,proto3" json:"encryptPublicKey,omitempty"`
|
||||||
EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"`
|
EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"`
|
||||||
Permissions ACLChangeUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=anytype.ACLChangeUserPermissions" json:"permissions,omitempty"`
|
Permissions ACLChangeUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=acl.ACLChangeUserPermissions" json:"permissions,omitempty"`
|
||||||
InviteId string `protobuf:"bytes,5,opt,name=InviteId,proto3" json:"InviteId,omitempty"`
|
InviteId string `protobuf:"bytes,5,opt,name=InviteId,proto3" json:"InviteId,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,7 +719,7 @@ func (m *ACLChangeUserInvite) Reset() { *m = ACLChangeUserInvite{} }
|
|||||||
func (m *ACLChangeUserInvite) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeUserInvite) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeUserInvite) ProtoMessage() {}
|
func (*ACLChangeUserInvite) ProtoMessage() {}
|
||||||
func (*ACLChangeUserInvite) Descriptor() ([]byte, []int) {
|
func (*ACLChangeUserInvite) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 7}
|
return fileDescriptor_37a022c841a51877, []int{1, 7}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeUserInvite) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeUserInvite) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -735,7 +795,7 @@ func (m *ACLChangeUserJoin) Reset() { *m = ACLChangeUserJoin{} }
|
|||||||
func (m *ACLChangeUserJoin) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeUserJoin) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeUserJoin) ProtoMessage() {}
|
func (*ACLChangeUserJoin) ProtoMessage() {}
|
||||||
func (*ACLChangeUserJoin) Descriptor() ([]byte, []int) {
|
func (*ACLChangeUserJoin) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 8}
|
return fileDescriptor_37a022c841a51877, []int{1, 8}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeUserJoin) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeUserJoin) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -808,7 +868,7 @@ func (m *ACLChangeUserRemove) Reset() { *m = ACLChangeUserRemove{} }
|
|||||||
func (m *ACLChangeUserRemove) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeUserRemove) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeUserRemove) ProtoMessage() {}
|
func (*ACLChangeUserRemove) ProtoMessage() {}
|
||||||
func (*ACLChangeUserRemove) Descriptor() ([]byte, []int) {
|
func (*ACLChangeUserRemove) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 9}
|
return fileDescriptor_37a022c841a51877, []int{1, 9}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeUserRemove) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeUserRemove) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -861,7 +921,7 @@ func (m *ACLChangeReadKeyReplace) Reset() { *m = ACLChangeReadKeyReplace
|
|||||||
func (m *ACLChangeReadKeyReplace) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeReadKeyReplace) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeReadKeyReplace) ProtoMessage() {}
|
func (*ACLChangeReadKeyReplace) ProtoMessage() {}
|
||||||
func (*ACLChangeReadKeyReplace) Descriptor() ([]byte, []int) {
|
func (*ACLChangeReadKeyReplace) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 10}
|
return fileDescriptor_37a022c841a51877, []int{1, 10}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeReadKeyReplace) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeReadKeyReplace) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -913,14 +973,14 @@ func (m *ACLChangeReadKeyReplace) GetEncryptedReadKey() []byte {
|
|||||||
|
|
||||||
type ACLChangeUserPermissionChange struct {
|
type ACLChangeUserPermissionChange struct {
|
||||||
Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
|
Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
|
||||||
Permissions ACLChangeUserPermissions `protobuf:"varint,2,opt,name=permissions,proto3,enum=anytype.ACLChangeUserPermissions" json:"permissions,omitempty"`
|
Permissions ACLChangeUserPermissions `protobuf:"varint,2,opt,name=permissions,proto3,enum=acl.ACLChangeUserPermissions" json:"permissions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ACLChangeUserPermissionChange) Reset() { *m = ACLChangeUserPermissionChange{} }
|
func (m *ACLChangeUserPermissionChange) Reset() { *m = ACLChangeUserPermissionChange{} }
|
||||||
func (m *ACLChangeUserPermissionChange) String() string { return proto.CompactTextString(m) }
|
func (m *ACLChangeUserPermissionChange) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ACLChangeUserPermissionChange) ProtoMessage() {}
|
func (*ACLChangeUserPermissionChange) ProtoMessage() {}
|
||||||
func (*ACLChangeUserPermissionChange) Descriptor() ([]byte, []int) {
|
func (*ACLChangeUserPermissionChange) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_37a022c841a51877, []int{0, 11}
|
return fileDescriptor_37a022c841a51877, []int{1, 11}
|
||||||
}
|
}
|
||||||
func (m *ACLChangeUserPermissionChange) XXX_Unmarshal(b []byte) error {
|
func (m *ACLChangeUserPermissionChange) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -964,21 +1024,22 @@ func (m *ACLChangeUserPermissionChange) GetPermissions() ACLChangeUserPermission
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
proto.RegisterEnum("anytype.ACLChangeUserPermissions", ACLChangeUserPermissions_name, ACLChangeUserPermissions_value)
|
proto.RegisterEnum("acl.ACLChangeUserPermissions", ACLChangeUserPermissions_name, ACLChangeUserPermissions_value)
|
||||||
proto.RegisterType((*ACLChange)(nil), "anytype.ACLChange")
|
proto.RegisterType((*RawChange)(nil), "acl.RawChange")
|
||||||
proto.RegisterType((*ACLChangeACLContentValue)(nil), "anytype.ACLChange.ACLContentValue")
|
proto.RegisterType((*ACLChange)(nil), "acl.ACLChange")
|
||||||
proto.RegisterType((*ACLChangeACLData)(nil), "anytype.ACLChange.ACLData")
|
proto.RegisterType((*ACLChangeACLContentValue)(nil), "acl.ACLChange.ACLContentValue")
|
||||||
proto.RegisterType((*ACLChangeACLSnapshot)(nil), "anytype.ACLChange.ACLSnapshot")
|
proto.RegisterType((*ACLChangeACLData)(nil), "acl.ACLChange.ACLData")
|
||||||
proto.RegisterType((*ACLChangeACLState)(nil), "anytype.ACLChange.ACLState")
|
proto.RegisterType((*ACLChangeACLSnapshot)(nil), "acl.ACLChange.ACLSnapshot")
|
||||||
proto.RegisterMapType((map[string]*ACLChangeUserInvite)(nil), "anytype.ACLChange.ACLState.InvitesEntry")
|
proto.RegisterType((*ACLChangeACLState)(nil), "acl.ACLChange.ACLState")
|
||||||
proto.RegisterType((*ACLChangeUserState)(nil), "anytype.ACLChange.UserState")
|
proto.RegisterMapType((map[string]*ACLChangeUserInvite)(nil), "acl.ACLChange.ACLState.InvitesEntry")
|
||||||
proto.RegisterType((*ACLChangeUserAdd)(nil), "anytype.ACLChange.UserAdd")
|
proto.RegisterType((*ACLChangeUserState)(nil), "acl.ACLChange.UserState")
|
||||||
proto.RegisterType((*ACLChangeUserConfirm)(nil), "anytype.ACLChange.UserConfirm")
|
proto.RegisterType((*ACLChangeUserAdd)(nil), "acl.ACLChange.UserAdd")
|
||||||
proto.RegisterType((*ACLChangeUserInvite)(nil), "anytype.ACLChange.UserInvite")
|
proto.RegisterType((*ACLChangeUserConfirm)(nil), "acl.ACLChange.UserConfirm")
|
||||||
proto.RegisterType((*ACLChangeUserJoin)(nil), "anytype.ACLChange.UserJoin")
|
proto.RegisterType((*ACLChangeUserInvite)(nil), "acl.ACLChange.UserInvite")
|
||||||
proto.RegisterType((*ACLChangeUserRemove)(nil), "anytype.ACLChange.UserRemove")
|
proto.RegisterType((*ACLChangeUserJoin)(nil), "acl.ACLChange.UserJoin")
|
||||||
proto.RegisterType((*ACLChangeReadKeyReplace)(nil), "anytype.ACLChange.ReadKeyReplace")
|
proto.RegisterType((*ACLChangeUserRemove)(nil), "acl.ACLChange.UserRemove")
|
||||||
proto.RegisterType((*ACLChangeUserPermissionChange)(nil), "anytype.ACLChange.UserPermissionChange")
|
proto.RegisterType((*ACLChangeReadKeyReplace)(nil), "acl.ACLChange.ReadKeyReplace")
|
||||||
|
proto.RegisterType((*ACLChangeUserPermissionChange)(nil), "acl.ACLChange.UserPermissionChange")
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -986,65 +1047,111 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptor_37a022c841a51877 = []byte{
|
var fileDescriptor_37a022c841a51877 = []byte{
|
||||||
// 915 bytes of a gzipped FileDescriptorProto
|
// 948 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4d, 0x6f, 0xe3, 0x44,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0xe3, 0x44,
|
||||||
0x18, 0xf6, 0x24, 0x4d, 0x1d, 0xbf, 0x0e, 0x6d, 0x18, 0xf5, 0x60, 0x79, 0x8b, 0x09, 0x15, 0x82,
|
0x14, 0xf7, 0xc4, 0x4d, 0x1d, 0x3f, 0x87, 0x36, 0x0c, 0x2b, 0xd6, 0x58, 0x4b, 0x88, 0xca, 0x0a,
|
||||||
0x08, 0xa1, 0x2c, 0xca, 0x22, 0xbe, 0x84, 0x04, 0x4d, 0x17, 0x48, 0x28, 0x87, 0xd5, 0xac, 0x00,
|
0x45, 0x08, 0xa5, 0xab, 0xac, 0x90, 0x56, 0x80, 0x2a, 0xda, 0x82, 0x36, 0xa1, 0x1c, 0x56, 0x53,
|
||||||
0x81, 0xc4, 0x61, 0x6a, 0x0f, 0xad, 0xb5, 0x89, 0x6d, 0x79, 0x26, 0x15, 0xb9, 0xf0, 0x0f, 0x10,
|
0x2d, 0x08, 0x6e, 0x53, 0x7b, 0x68, 0xad, 0x75, 0x6c, 0xe3, 0x99, 0x14, 0xe5, 0x82, 0xc4, 0x89,
|
||||||
0xfc, 0x16, 0xae, 0x1c, 0xb8, 0xee, 0x71, 0x8f, 0x1c, 0x51, 0xfb, 0x0f, 0xf8, 0x05, 0x68, 0x3e,
|
0x2b, 0x67, 0xbe, 0x0a, 0x5f, 0x60, 0x8f, 0x7b, 0xe4, 0x06, 0x6a, 0xef, 0x5c, 0xf8, 0x02, 0x68,
|
||||||
0xec, 0x38, 0xa9, 0x1d, 0x24, 0xb4, 0x12, 0xe2, 0x10, 0x69, 0xe6, 0x99, 0xe7, 0x1d, 0xbf, 0x1f,
|
0xfe, 0xd8, 0x71, 0x12, 0x6f, 0x24, 0xa4, 0x15, 0x12, 0x87, 0x4a, 0x33, 0xbf, 0xf7, 0x7b, 0xd3,
|
||||||
0xcf, 0xfb, 0x4e, 0xe0, 0xad, 0xec, 0xc9, 0xe5, 0x7d, 0x1a, 0xce, 0xe5, 0x2f, 0xbc, 0xa2, 0xc9,
|
0xf7, 0xde, 0xef, 0xbd, 0x17, 0xc3, 0x83, 0xfc, 0xd9, 0xe5, 0x21, 0x0d, 0x13, 0xf9, 0x17, 0x5e,
|
||||||
0x25, 0xe3, 0x72, 0x99, 0x5d, 0xdc, 0xcf, 0xf2, 0x54, 0xa4, 0xbc, 0x82, 0x8f, 0x14, 0x82, 0x6d,
|
0xd1, 0xf4, 0x92, 0x71, 0x79, 0xcc, 0x2f, 0x0e, 0xf3, 0x22, 0x13, 0x19, 0xaf, 0xe1, 0x23, 0x85,
|
||||||
0x9a, 0xac, 0xc4, 0x2a, 0x63, 0x27, 0xbf, 0x1d, 0x81, 0x73, 0x7a, 0xf6, 0xc5, 0x99, 0x3a, 0xc5,
|
0x60, 0x9b, 0x86, 0xc9, 0xc1, 0x39, 0xb8, 0x84, 0xfe, 0x70, 0xaa, 0x0c, 0xd8, 0x07, 0x27, 0xa7,
|
||||||
0x03, 0x70, 0x45, 0xce, 0xd8, 0x94, 0xd1, 0x68, 0x16, 0x71, 0x0f, 0x0d, 0xda, 0x43, 0x87, 0x54,
|
0x8b, 0x24, 0xa3, 0x91, 0x8f, 0x06, 0x68, 0xd8, 0x25, 0xe5, 0x15, 0xdf, 0x03, 0x97, 0xc7, 0x97,
|
||||||
0x21, 0x1c, 0x00, 0xd0, 0x70, 0x5e, 0x10, 0x5a, 0x8a, 0x50, 0x41, 0xf0, 0x6b, 0x70, 0xc0, 0x13,
|
0x29, 0x15, 0xf3, 0x82, 0xf9, 0x2d, 0x65, 0x5b, 0x02, 0x78, 0x0f, 0x5a, 0x71, 0xe4, 0xdb, 0x03,
|
||||||
0x9a, 0xf1, 0xab, 0x54, 0x4c, 0x28, 0x67, 0xb3, 0xc8, 0x6b, 0x0f, 0xd0, 0xd0, 0x21, 0x5b, 0x28,
|
0x34, 0x74, 0x49, 0x2b, 0x8e, 0x0e, 0xfe, 0x7e, 0x03, 0xdc, 0xe3, 0xd3, 0x2f, 0xcd, 0xab, 0x03,
|
||||||
0x7e, 0x1b, 0x6c, 0x1a, 0xce, 0x1f, 0x52, 0x41, 0xbd, 0xbd, 0x01, 0x1a, 0xba, 0x63, 0x7f, 0x64,
|
0xf0, 0x44, 0xc1, 0xd8, 0x84, 0xd1, 0x68, 0x1a, 0x71, 0x1f, 0x0d, 0xec, 0xa1, 0x4b, 0xea, 0x10,
|
||||||
0x5c, 0x1a, 0x95, 0xee, 0xc8, 0x95, 0x64, 0x90, 0x82, 0x2a, 0xfd, 0x33, 0x71, 0x28, 0xcb, 0xce,
|
0xee, 0x03, 0xd0, 0x30, 0x29, 0x09, 0x2d, 0x45, 0xa8, 0x21, 0xf8, 0x3d, 0xd8, 0xe3, 0x29, 0xcd,
|
||||||
0x00, 0x0d, 0x7b, 0xa4, 0x0a, 0xe1, 0x11, 0xe0, 0x70, 0x99, 0xe7, 0x2c, 0x11, 0x84, 0xd1, 0xe8,
|
0xf9, 0x55, 0x26, 0x4e, 0x28, 0x67, 0xd3, 0xf2, 0x7f, 0xad, 0xa1, 0xf8, 0x01, 0x38, 0x34, 0x4c,
|
||||||
0x9c, 0xad, 0xa6, 0x94, 0x5f, 0x79, 0xfb, 0x03, 0x34, 0xdc, 0x23, 0x35, 0x27, 0xf8, 0x18, 0x1c,
|
0x3e, 0xa3, 0x82, 0xfa, 0x3b, 0x03, 0x34, 0xf4, 0xc6, 0x6f, 0x8e, 0x68, 0x98, 0x8c, 0xaa, 0x50,
|
||||||
0x11, 0x2f, 0x18, 0x17, 0x74, 0x91, 0x79, 0xf6, 0x00, 0x0d, 0xdb, 0x64, 0x0d, 0x60, 0x1f, 0xba,
|
0xe4, 0x49, 0x5a, 0x49, 0x49, 0x93, 0xb1, 0x99, 0xa2, 0x28, 0xaf, 0xb6, 0xca, 0xac, 0x0e, 0xe1,
|
||||||
0x71, 0xc4, 0x12, 0x11, 0x8b, 0x95, 0xd7, 0x55, 0x71, 0x94, 0x7b, 0xff, 0xd7, 0x36, 0x1c, 0x4a,
|
0x11, 0xe0, 0x70, 0x5e, 0x14, 0x2c, 0x15, 0x84, 0xd1, 0xe8, 0x8c, 0x2d, 0x26, 0x94, 0x5f, 0xf9,
|
||||||
0x57, 0xd3, 0x44, 0xb0, 0x44, 0x7c, 0x45, 0xe7, 0x4b, 0x86, 0xdf, 0x01, 0x7b, 0xc9, 0x59, 0x7e,
|
0xbb, 0x03, 0x34, 0xdc, 0x21, 0x0d, 0x16, 0x59, 0x29, 0x11, 0xcf, 0x18, 0x17, 0x74, 0x96, 0xfb,
|
||||||
0x1a, 0x45, 0x1e, 0x6a, 0x8c, 0xea, 0x4b, 0xcd, 0x98, 0x5a, 0xa4, 0x20, 0xe3, 0x8f, 0x00, 0xe4,
|
0xce, 0x00, 0x0d, 0x6d, 0xb2, 0x04, 0x70, 0x00, 0x9d, 0x38, 0x62, 0xa9, 0x88, 0xc5, 0xc2, 0xef,
|
||||||
0x92, 0xb0, 0x45, 0x7a, 0xcd, 0xbc, 0x96, 0x32, 0x7d, 0xa9, 0xc1, 0x54, 0x93, 0xa6, 0x16, 0xa9,
|
0xa8, 0x1c, 0xaa, 0x7b, 0xf0, 0xab, 0x0d, 0xfb, 0x32, 0xd4, 0x2c, 0x15, 0x2c, 0x15, 0x5f, 0xd1,
|
||||||
0x98, 0xe0, 0xef, 0xe0, 0x48, 0xee, 0x1e, 0xb1, 0x7c, 0x11, 0x73, 0x1e, 0xa7, 0x89, 0x36, 0x50,
|
0x64, 0xce, 0xf0, 0x18, 0x9c, 0x39, 0x67, 0xc5, 0x71, 0xa4, 0x15, 0xd9, 0xcc, 0xe8, 0xa9, 0xb6,
|
||||||
0xc9, 0x77, 0xc7, 0xaf, 0x37, 0x5c, 0xb5, 0x4d, 0x9f, 0x5a, 0xa4, 0xf6, 0x9a, 0xc2, 0xbf, 0x59,
|
0x4e, 0x2c, 0x52, 0x12, 0xf1, 0xc7, 0x00, 0xf2, 0x48, 0xd8, 0x2c, 0xbb, 0xd6, 0x62, 0x79, 0xe3,
|
||||||
0x72, 0x1d, 0x0b, 0x66, 0x0a, 0xd6, 0xe4, 0x9f, 0x26, 0x15, 0xfe, 0xe9, 0x1d, 0x7e, 0x1f, 0xba,
|
0xb7, 0x1a, 0xdc, 0x34, 0x61, 0x62, 0x91, 0x1a, 0x1d, 0x7f, 0x03, 0x77, 0xe4, 0xed, 0x09, 0x2b,
|
||||||
0x72, 0xf7, 0x79, 0x1a, 0x27, 0xaa, 0x6a, 0xee, 0xf8, 0x5e, 0x83, 0xb9, 0xa4, 0x4c, 0x2d, 0x52,
|
0x66, 0x31, 0xe7, 0x71, 0x96, 0x6a, 0x07, 0x55, 0x70, 0x6f, 0xfc, 0x6e, 0xc3, 0x33, 0xeb, 0xd4,
|
||||||
0xd2, 0xf1, 0x04, 0x5c, 0xb9, 0x3e, 0x4b, 0x93, 0xef, 0xe3, 0x7c, 0xa1, 0x4a, 0xe9, 0x8e, 0x83,
|
0x89, 0x45, 0x1a, 0x9f, 0x28, 0xe3, 0x9a, 0xa6, 0xd7, 0xb1, 0x60, 0x46, 0xa0, 0xa6, 0xb8, 0x34,
|
||||||
0x06, 0x6b, 0xc3, 0x9a, 0x5a, 0xa4, 0x6a, 0x34, 0xb1, 0xa1, 0x73, 0x2d, 0x0b, 0xe4, 0xff, 0x8c,
|
0xa1, 0x8c, 0x4b, 0xdf, 0xf0, 0x87, 0xd0, 0x91, 0xb7, 0x2f, 0xb2, 0x38, 0x55, 0x2a, 0x79, 0xe3,
|
||||||
0xc0, 0x36, 0xaa, 0xc2, 0x1f, 0x83, 0x4b, 0xc3, 0xf9, 0x63, 0xa3, 0x4b, 0x53, 0xb0, 0xa0, 0x5e,
|
0xbb, 0x0d, 0xae, 0xd2, 0x3c, 0xb1, 0x48, 0x45, 0xc5, 0x47, 0xe0, 0xc9, 0xf3, 0x69, 0x96, 0x7e,
|
||||||
0x86, 0x05, 0x8b, 0x54, 0x4d, 0xf0, 0x44, 0x35, 0x83, 0x51, 0x80, 0x6a, 0x06, 0x77, 0x7c, 0x52,
|
0x17, 0x17, 0x33, 0x25, 0x9b, 0x37, 0x0e, 0x1a, 0x3c, 0x0d, 0x63, 0x62, 0x91, 0xba, 0xc3, 0x89,
|
||||||
0x7f, 0x41, 0x55, 0x26, 0xa4, 0x62, 0xe5, 0x7f, 0x0a, 0x6e, 0xe5, 0x7e, 0xfc, 0x2e, 0x74, 0xe5,
|
0x03, 0xed, 0x6b, 0x29, 0x44, 0xf0, 0x33, 0x02, 0xc7, 0x74, 0x0f, 0xfe, 0x04, 0x3c, 0x1a, 0x26,
|
||||||
0x17, 0x04, 0x15, 0xcc, 0x78, 0x74, 0xaf, 0xc1, 0x23, 0x49, 0x21, 0x25, 0xd9, 0xff, 0xa9, 0x05,
|
0xe7, 0xa6, 0xf7, 0x8c, 0x30, 0xc1, 0x66, 0xab, 0x95, 0x0c, 0x52, 0xa7, 0xe3, 0x23, 0xd5, 0xec,
|
||||||
0xdd, 0x02, 0xc6, 0xaf, 0xc2, 0x0b, 0xf9, 0x5a, 0xe4, 0x4c, 0x77, 0xf2, 0x1e, 0xd9, 0x04, 0xf1,
|
0x46, 0x65, 0xd5, 0xec, 0xde, 0xb8, 0xbf, 0xe9, 0x5c, 0x6f, 0x03, 0x52, 0xf3, 0x08, 0x4e, 0xc0,
|
||||||
0x87, 0xba, 0xaa, 0xca, 0x84, 0x1b, 0xf7, 0x8f, 0x1b, 0x12, 0xab, 0x3f, 0x57, 0xe1, 0xe3, 0x09,
|
0xab, 0xbd, 0x8d, 0x1f, 0x42, 0x47, 0xbe, 0x2e, 0xa8, 0x60, 0x26, 0x92, 0xbb, 0x0d, 0x91, 0x48,
|
||||||
0xd8, 0xb1, 0x2a, 0x2e, 0xf7, 0xda, 0xca, 0x74, 0xb8, 0xc3, 0xd1, 0x91, 0xd6, 0x01, 0xff, 0x24,
|
0x33, 0xa9, 0x88, 0xc1, 0x4f, 0x2d, 0xe8, 0x94, 0x30, 0xbe, 0x0f, 0xaf, 0x15, 0xcb, 0x06, 0x66,
|
||||||
0x11, 0xf9, 0x8a, 0x14, 0x86, 0xfe, 0x37, 0xd0, 0xab, 0x1e, 0xe0, 0x3e, 0xb4, 0x9f, 0xb0, 0x95,
|
0x7a, 0x42, 0x77, 0xc8, 0x2a, 0x88, 0x1f, 0x69, 0xf5, 0x94, 0x0b, 0x37, 0x61, 0xfb, 0x0d, 0x85,
|
||||||
0x0a, 0xdc, 0x21, 0x72, 0x89, 0x1f, 0x98, 0xca, 0xfd, 0x43, 0x53, 0xe8, 0x5b, 0x88, 0xe6, 0x7e,
|
0xd4, 0xff, 0xaa, 0xc6, 0xc5, 0x47, 0xe0, 0xc4, 0x4a, 0x44, 0xee, 0xdb, 0xca, 0xed, 0xfe, 0x4b,
|
||||||
0xd0, 0x7a, 0x0f, 0xf9, 0xb7, 0x08, 0x9c, 0xd2, 0xf1, 0x8d, 0x46, 0x46, 0x9b, 0x8d, 0x2c, 0x93,
|
0x02, 0x1c, 0x69, 0xad, 0xf9, 0xe7, 0xa9, 0x28, 0x16, 0xa4, 0x74, 0x0a, 0x9e, 0x42, 0xb7, 0x6e,
|
||||||
0xc5, 0x92, 0x30, 0x5f, 0x65, 0x22, 0x4e, 0x93, 0x73, 0xb6, 0x52, 0x9f, 0xea, 0x91, 0x4d, 0x10,
|
0xc0, 0x3d, 0xb0, 0x9f, 0xb1, 0x85, 0x4a, 0xd6, 0x25, 0xf2, 0x88, 0x0f, 0x8d, 0x4a, 0x5b, 0x9a,
|
||||||
0xbf, 0x09, 0x2f, 0x1a, 0x80, 0x45, 0x66, 0x80, 0xe8, 0xc0, 0x7b, 0xe4, 0xee, 0x01, 0x7e, 0x08,
|
0x5d, 0xbf, 0x40, 0x34, 0xef, 0xa3, 0xd6, 0x23, 0x14, 0xfc, 0x81, 0xc0, 0xad, 0x02, 0x5e, 0x19,
|
||||||
0x6e, 0x56, 0x36, 0x11, 0x57, 0x1d, 0x73, 0x50, 0x2b, 0x8d, 0xcd, 0x36, 0xe4, 0xa4, 0x6a, 0x26,
|
0x4c, 0xb4, 0x3a, 0x98, 0xb2, 0x40, 0x2c, 0x0d, 0x8b, 0x45, 0x2e, 0xe2, 0x2c, 0x3d, 0x63, 0x0b,
|
||||||
0xc7, 0xdd, 0x8c, 0x1b, 0x0d, 0xb3, 0x48, 0x35, 0x4e, 0x97, 0x54, 0x21, 0xff, 0x77, 0x04, 0xb6,
|
0xb3, 0x00, 0x57, 0x41, 0xfc, 0x01, 0xbc, 0x6e, 0x00, 0x16, 0x99, 0x85, 0xa0, 0x13, 0xee, 0x92,
|
||||||
0x99, 0x27, 0xff, 0xcf, 0x18, 0xfd, 0xcf, 0xc0, 0xad, 0x34, 0xee, 0xce, 0x20, 0x8e, 0xc1, 0x31,
|
0x4d, 0x03, 0xfe, 0x14, 0xbc, 0xbc, 0x1a, 0x10, 0xae, 0xa6, 0x61, 0x6f, 0xa3, 0x0d, 0x56, 0xc7,
|
||||||
0x03, 0x73, 0x16, 0xa9, 0x00, 0x1c, 0xb2, 0x06, 0xfc, 0xbf, 0x10, 0xc0, 0x5a, 0x0a, 0x78, 0x08,
|
0x8b, 0x93, 0xba, 0x8b, 0x5c, 0x5d, 0x53, 0x6e, 0xfa, 0x94, 0x45, 0x6a, 0x28, 0x3a, 0xa4, 0x0e,
|
||||||
0x87, 0x34, 0x0c, 0x59, 0x26, 0x1e, 0x2d, 0x2f, 0xe6, 0x71, 0x78, 0x6e, 0x64, 0xd5, 0x23, 0xdb,
|
0x05, 0xbf, 0x21, 0x70, 0xcc, 0x7e, 0xf8, 0xff, 0xe5, 0x17, 0x3c, 0x06, 0xaf, 0x36, 0x98, 0x5b,
|
||||||
0x30, 0x7e, 0x03, 0xfa, 0x26, 0xb8, 0x35, 0x55, 0xa7, 0xe7, 0x0e, 0xfe, 0x9f, 0xa8, 0xc0, 0x87,
|
0x13, 0xb8, 0x07, 0xae, 0x59, 0x7e, 0xd3, 0x48, 0x05, 0xef, 0x92, 0x25, 0x10, 0xfc, 0x85, 0x00,
|
||||||
0xae, 0x8e, 0x69, 0xa6, 0x25, 0xe0, 0x90, 0x72, 0xef, 0x3f, 0x45, 0xd0, 0x2d, 0xa6, 0xe6, 0x73,
|
0x96, 0x2d, 0x80, 0x87, 0xb0, 0x4f, 0xc3, 0x90, 0xe5, 0xe2, 0xc9, 0xfc, 0x22, 0x89, 0xc3, 0x33,
|
||||||
0x10, 0x40, 0x99, 0xb4, 0xc7, 0xf1, 0x65, 0x42, 0xc5, 0x32, 0xd7, 0x2f, 0x48, 0x99, 0xb4, 0x12,
|
0xd3, 0x4a, 0x5d, 0xb2, 0x0e, 0xe3, 0xf7, 0xa1, 0x67, 0x12, 0x5b, 0x52, 0x75, 0x69, 0x36, 0xf0,
|
||||||
0xc6, 0x27, 0xd0, 0x5b, 0x8f, 0xf7, 0x59, 0xa4, 0x62, 0x73, 0xc8, 0x06, 0x56, 0x9f, 0xac, 0x4e,
|
0xff, 0x5c, 0xfd, 0x00, 0x3a, 0x3a, 0x9f, 0xa9, 0x96, 0xde, 0x25, 0xd5, 0x3d, 0x78, 0x8e, 0xa0,
|
||||||
0x43, 0xb2, 0xfc, 0xa5, 0x2e, 0x9f, 0x79, 0xd0, 0x76, 0xc5, 0x72, 0x0e, 0x87, 0x66, 0x90, 0x11,
|
0x53, 0x6e, 0xc3, 0x57, 0x20, 0x7c, 0x55, 0xb0, 0xf3, 0xea, 0x0b, 0xc0, 0xae, 0x17, 0xac, 0x82,
|
||||||
0x96, 0xcd, 0x69, 0x58, 0x4e, 0xa0, 0x57, 0x6a, 0x52, 0x4b, 0x36, 0x98, 0x64, 0xdb, 0xd2, 0xff,
|
0xf1, 0x01, 0x74, 0x97, 0x2b, 0x7b, 0x1a, 0xa9, 0xbc, 0x5c, 0xb2, 0x82, 0x35, 0x17, 0xaa, 0xfd,
|
||||||
0x11, 0x0e, 0x36, 0x29, 0xcf, 0x21, 0x8d, 0x6b, 0x45, 0x95, 0xf1, 0x99, 0x3c, 0xde, 0xc1, 0xfd,
|
0x92, 0x42, 0x05, 0xdf, 0x6b, 0xe9, 0xcc, 0x8f, 0xd3, 0xb6, 0x5c, 0x1e, 0xc3, 0xbe, 0x59, 0x58,
|
||||||
0x1f, 0xe0, 0xa8, 0xee, 0x29, 0xde, 0xe9, 0xc5, 0x96, 0xae, 0x5a, 0xff, 0x4a, 0x57, 0x27, 0xa7,
|
0x84, 0xe5, 0x09, 0x0d, 0xab, 0x6d, 0xf3, 0xf6, 0x5a, 0x59, 0xc9, 0x0a, 0x8b, 0xac, 0x7b, 0x05,
|
||||||
0x70, 0xb8, 0x75, 0x8e, 0x1d, 0xe8, 0x9c, 0x46, 0x8b, 0x38, 0xe9, 0x5b, 0x18, 0x60, 0xff, 0xeb,
|
0x3f, 0xc2, 0xde, 0x2a, 0xe5, 0x15, 0x94, 0x70, 0xd9, 0x49, 0x55, 0x6e, 0xa6, 0x86, 0x1b, 0x78,
|
||||||
0x3c, 0x16, 0x2c, 0xef, 0x23, 0xb9, 0x96, 0xee, 0xb2, 0xbc, 0xdf, 0xc2, 0x2e, 0xd8, 0xba, 0x44,
|
0x20, 0xe0, 0x4e, 0xd3, 0xcf, 0xea, 0xd6, 0x28, 0xd6, 0xfa, 0xa9, 0xf5, 0xaf, 0xfb, 0xe9, 0xe0,
|
||||||
0x51, 0xbf, 0x3d, 0x79, 0xf9, 0xe9, 0x4d, 0x80, 0x9e, 0xdd, 0x04, 0xe8, 0xcf, 0x9b, 0x00, 0xfd,
|
0x18, 0xf6, 0xd7, 0xec, 0xd8, 0x85, 0xf6, 0x71, 0x34, 0x8b, 0xd3, 0x9e, 0x85, 0x01, 0x76, 0xbf,
|
||||||
0x72, 0x1b, 0x58, 0xcf, 0x6e, 0x03, 0xeb, 0x8f, 0xdb, 0xc0, 0xfa, 0xb6, 0xa3, 0xfe, 0x7f, 0x5e,
|
0x2e, 0x62, 0xc1, 0x8a, 0x1e, 0x92, 0x67, 0x19, 0x2a, 0x2b, 0x7a, 0x2d, 0xec, 0x81, 0xa3, 0xa5,
|
||||||
0xec, 0xab, 0xbf, 0x9b, 0x0f, 0xfe, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x12, 0x23, 0x4c, 0xb6, 0xa2,
|
0x89, 0x7a, 0xf6, 0xc9, 0x3b, 0xcf, 0x6f, 0xfa, 0xe8, 0xc5, 0x4d, 0x1f, 0xfd, 0x79, 0xd3, 0x47,
|
||||||
0x0a, 0x00, 0x00,
|
0xbf, 0xdc, 0xf6, 0xad, 0x17, 0xb7, 0x7d, 0xeb, 0xf7, 0xdb, 0xbe, 0xf5, 0x6d, 0x5b, 0x7d, 0x88,
|
||||||
|
0x5e, 0xec, 0xaa, 0xef, 0xce, 0x87, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x2a, 0xe8, 0x23, 0x71,
|
||||||
|
0xab, 0x0a, 0x00, 0x00,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *RawChange) Marshal() (dAtA []byte, err error) {
|
||||||
|
size := m.Size()
|
||||||
|
dAtA = make([]byte, size)
|
||||||
|
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dAtA[:n], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *RawChange) MarshalTo(dAtA []byte) (int, error) {
|
||||||
|
size := m.Size()
|
||||||
|
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *RawChange) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||||
|
i := len(dAtA)
|
||||||
|
_ = i
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
if len(m.Id) > 0 {
|
||||||
|
i -= len(m.Id)
|
||||||
|
copy(dAtA[i:], m.Id)
|
||||||
|
i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Id)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x1a
|
||||||
|
}
|
||||||
|
if len(m.Signature) > 0 {
|
||||||
|
i -= len(m.Signature)
|
||||||
|
copy(dAtA[i:], m.Signature)
|
||||||
|
i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Signature)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x12
|
||||||
|
}
|
||||||
|
if len(m.Payload) > 0 {
|
||||||
|
i -= len(m.Payload)
|
||||||
|
copy(dAtA[i:], m.Payload)
|
||||||
|
i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Payload)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0xa
|
||||||
|
}
|
||||||
|
return len(dAtA) - i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ACLChange) Marshal() (dAtA []byte, err error) {
|
func (m *ACLChange) Marshal() (dAtA []byte, err error) {
|
||||||
@ -1855,6 +1962,27 @@ func encodeVarintAclchanges(dAtA []byte, offset int, v uint64) int {
|
|||||||
dAtA[offset] = uint8(v)
|
dAtA[offset] = uint8(v)
|
||||||
return base
|
return base
|
||||||
}
|
}
|
||||||
|
func (m *RawChange) Size() (n int) {
|
||||||
|
if m == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
l = len(m.Payload)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovAclchanges(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.Signature)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovAclchanges(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.Id)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovAclchanges(uint64(l))
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
func (m *ACLChange) Size() (n int) {
|
func (m *ACLChange) Size() (n int) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return 0
|
return 0
|
||||||
@ -2244,6 +2372,156 @@ func sovAclchanges(x uint64) (n int) {
|
|||||||
func sozAclchanges(x uint64) (n int) {
|
func sozAclchanges(x uint64) (n int) {
|
||||||
return sovAclchanges(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
return sovAclchanges(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||||
}
|
}
|
||||||
|
func (m *RawChange) Unmarshal(dAtA []byte) error {
|
||||||
|
l := len(dAtA)
|
||||||
|
iNdEx := 0
|
||||||
|
for iNdEx < l {
|
||||||
|
preIndex := iNdEx
|
||||||
|
var wire uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowAclchanges
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
wire |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldNum := int32(wire >> 3)
|
||||||
|
wireType := int(wire & 0x7)
|
||||||
|
if wireType == 4 {
|
||||||
|
return fmt.Errorf("proto: RawChange: wiretype end group for non-group")
|
||||||
|
}
|
||||||
|
if fieldNum <= 0 {
|
||||||
|
return fmt.Errorf("proto: RawChange: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||||
|
}
|
||||||
|
switch fieldNum {
|
||||||
|
case 1:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType)
|
||||||
|
}
|
||||||
|
var byteLen int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowAclchanges
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
byteLen |= int(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if byteLen < 0 {
|
||||||
|
return ErrInvalidLengthAclchanges
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + byteLen
|
||||||
|
if postIndex < 0 {
|
||||||
|
return ErrInvalidLengthAclchanges
|
||||||
|
}
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...)
|
||||||
|
if m.Payload == nil {
|
||||||
|
m.Payload = []byte{}
|
||||||
|
}
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 2:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType)
|
||||||
|
}
|
||||||
|
var byteLen int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowAclchanges
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
byteLen |= int(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if byteLen < 0 {
|
||||||
|
return ErrInvalidLengthAclchanges
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + byteLen
|
||||||
|
if postIndex < 0 {
|
||||||
|
return ErrInvalidLengthAclchanges
|
||||||
|
}
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...)
|
||||||
|
if m.Signature == nil {
|
||||||
|
m.Signature = []byte{}
|
||||||
|
}
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 3:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowAclchanges
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthAclchanges
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex < 0 {
|
||||||
|
return ErrInvalidLengthAclchanges
|
||||||
|
}
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.Id = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
default:
|
||||||
|
iNdEx = preIndex
|
||||||
|
skippy, err := skipAclchanges(dAtA[iNdEx:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||||
|
return ErrInvalidLengthAclchanges
|
||||||
|
}
|
||||||
|
if (iNdEx + skippy) > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
iNdEx += skippy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if iNdEx > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
func (m *ACLChange) Unmarshal(dAtA []byte) error {
|
func (m *ACLChange) Unmarshal(dAtA []byte) error {
|
||||||
l := len(dAtA)
|
l := len(dAtA)
|
||||||
iNdEx := 0
|
iNdEx := 0
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
package anytype;
|
package acl;
|
||||||
option go_package = "aclpb";
|
option go_package = "aclpb";
|
||||||
|
|
||||||
|
message RawChange {
|
||||||
|
bytes payload = 1;
|
||||||
|
bytes signature = 2;
|
||||||
|
string id = 3;
|
||||||
|
}
|
||||||
|
|
||||||
// the element of change tree used to store and internal apply smartBlock history
|
// the element of change tree used to store and internal apply smartBlock history
|
||||||
message ACLChange {
|
message ACLChange {
|
||||||
repeated string treeHeadIds = 1;
|
repeated string treeHeadIds = 1;
|
||||||
|
|||||||
@ -2,8 +2,12 @@ package acltree
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
||||||
|
"go.uber.org/zap"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,6 +22,7 @@ const (
|
|||||||
type AddResult struct {
|
type AddResult struct {
|
||||||
OldHeads []string
|
OldHeads []string
|
||||||
Heads []string
|
Heads []string
|
||||||
|
Added []*aclpb.RawChange
|
||||||
// TODO: add summary for changes
|
// TODO: add summary for changes
|
||||||
Summary AddResultSummary
|
Summary AddResultSummary
|
||||||
}
|
}
|
||||||
@ -27,15 +32,38 @@ type TreeUpdateListener interface {
|
|||||||
Rebuild(tree ACLTree)
|
Rebuild(tree ACLTree)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NoOpListener struct{}
|
||||||
|
|
||||||
|
func (n NoOpListener) Update(tree ACLTree) {}
|
||||||
|
|
||||||
|
func (n NoOpListener) Rebuild(tree ACLTree) {}
|
||||||
|
|
||||||
|
type RWLocker interface {
|
||||||
|
sync.Locker
|
||||||
|
RLock()
|
||||||
|
RUnlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrNoCommonSnapshot = errors.New("trees doesn't have a common snapshot")
|
||||||
|
|
||||||
type ACLTree interface {
|
type ACLTree interface {
|
||||||
|
RWLocker
|
||||||
|
ID() string
|
||||||
|
Header() *treepb.TreeHeader
|
||||||
ACLState() *ACLState
|
ACLState() *ACLState
|
||||||
AddContent(ctx context.Context, f func(builder ChangeBuilder) error) (*Change, error)
|
AddContent(ctx context.Context, f func(builder ChangeBuilder) error) (*aclpb.RawChange, error)
|
||||||
AddChanges(ctx context.Context, changes ...*Change) (AddResult, error)
|
AddRawChanges(ctx context.Context, changes ...*aclpb.RawChange) (AddResult, error)
|
||||||
Heads() []string
|
Heads() []string
|
||||||
Root() *Change
|
Root() *Change
|
||||||
Iterate(func(change *Change) bool)
|
Iterate(func(change *Change) bool)
|
||||||
IterateFrom(string, func(change *Change) bool)
|
IterateFrom(string, func(change *Change) bool)
|
||||||
HasChange(string) bool
|
HasChange(string) bool
|
||||||
|
SnapshotPath() []string
|
||||||
|
ChangesAfterCommonSnapshot(snapshotPath []string) ([]*aclpb.RawChange, error)
|
||||||
|
Storage() treestorage.TreeStorage
|
||||||
|
DebugDump() (string, error)
|
||||||
|
|
||||||
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type aclTree struct {
|
type aclTree struct {
|
||||||
@ -43,6 +71,8 @@ type aclTree struct {
|
|||||||
accountData *account.AccountData
|
accountData *account.AccountData
|
||||||
updateListener TreeUpdateListener
|
updateListener TreeUpdateListener
|
||||||
|
|
||||||
|
id string
|
||||||
|
header *treepb.TreeHeader
|
||||||
fullTree *Tree
|
fullTree *Tree
|
||||||
aclTreeFromStart *Tree // TODO: right now we don't use it, we can probably have only local var for now. This tree is built from start of the document
|
aclTreeFromStart *Tree // TODO: right now we don't use it, we can probably have only local var for now. This tree is built from start of the document
|
||||||
aclState *ACLState
|
aclState *ACLState
|
||||||
@ -90,6 +120,14 @@ func BuildACLTree(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
aclTree.id, err = t.TreeID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
aclTree.header, err = t.Header()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
listener.Rebuild(aclTree)
|
listener.Rebuild(aclTree)
|
||||||
|
|
||||||
@ -192,17 +230,25 @@ func (a *aclTree) rebuildFromStorage(fromStart bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *aclTree) ID() string {
|
||||||
|
return a.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclTree) Header() *treepb.TreeHeader {
|
||||||
|
return a.header
|
||||||
|
}
|
||||||
|
|
||||||
func (a *aclTree) ACLState() *ACLState {
|
func (a *aclTree) ACLState() *ACLState {
|
||||||
a.RLock()
|
|
||||||
defer a.RUnlock()
|
|
||||||
return a.aclState
|
return a.aclState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclTree) AddContent(ctx context.Context, build func(builder ChangeBuilder) error) (*Change, error) {
|
func (a *aclTree) Storage() treestorage.TreeStorage {
|
||||||
|
return a.treeStorage
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclTree) AddContent(ctx context.Context, build func(builder ChangeBuilder) error) (*aclpb.RawChange, error) {
|
||||||
// TODO: add snapshot creation logic
|
// TODO: add snapshot creation logic
|
||||||
a.Lock()
|
|
||||||
defer func() {
|
defer func() {
|
||||||
a.Unlock()
|
|
||||||
// TODO: should this be called in a separate goroutine to prevent accidental cycles (tree->updater->tree)
|
// TODO: should this be called in a separate goroutine to prevent accidental cycles (tree->updater->tree)
|
||||||
a.updateListener.Update(a)
|
a.updateListener.Update(a)
|
||||||
}()
|
}()
|
||||||
@ -218,12 +264,13 @@ func (a *aclTree) AddContent(ctx context.Context, build func(builder ChangeBuild
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
a.fullTree.AddFast(ch)
|
a.fullTree.AddFast(ch)
|
||||||
|
rawCh := &aclpb.RawChange{
|
||||||
err = a.treeStorage.AddRawChange(&treestorage.RawChange{
|
|
||||||
Payload: marshalled,
|
Payload: marshalled,
|
||||||
Signature: ch.Signature(),
|
Signature: ch.Signature(),
|
||||||
Id: ch.Id,
|
Id: ch.Id,
|
||||||
})
|
}
|
||||||
|
|
||||||
|
err = a.treeStorage.AddRawChange(rawCh)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -232,15 +279,24 @@ func (a *aclTree) AddContent(ctx context.Context, build func(builder ChangeBuild
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return ch, nil
|
return rawCh, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclTree) AddChanges(ctx context.Context, changes ...*Change) (AddResult, error) {
|
func (a *aclTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.RawChange) (AddResult, error) {
|
||||||
a.Lock()
|
|
||||||
// TODO: make proper error handling, because there are a lot of corner cases where this will break
|
// TODO: make proper error handling, because there are a lot of corner cases where this will break
|
||||||
var err error
|
var err error
|
||||||
var mode Mode
|
var mode Mode
|
||||||
|
|
||||||
|
var changes []*Change // TODO: = addChangesBuf[:0] ...
|
||||||
|
for _, ch := range rawChanges {
|
||||||
|
change, err := NewFromRawChange(ch)
|
||||||
|
// TODO: think what if we will have incorrect signatures on rawChanges, how everything will work
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
changes = append(changes, change)
|
||||||
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -256,7 +312,6 @@ func (a *aclTree) AddChanges(ctx context.Context, changes ...*Change) (AddResult
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
a.Unlock()
|
|
||||||
switch mode {
|
switch mode {
|
||||||
case Append:
|
case Append:
|
||||||
a.updateListener.Update(a)
|
a.updateListener.Update(a)
|
||||||
@ -267,6 +322,16 @@ func (a *aclTree) AddChanges(ctx context.Context, changes ...*Change) (AddResult
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
getAddedChanges := func() []*aclpb.RawChange {
|
||||||
|
var added []*aclpb.RawChange
|
||||||
|
for _, ch := range rawChanges {
|
||||||
|
if _, exists := a.fullTree.attached[ch.Id]; exists {
|
||||||
|
added = append(added, ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return added
|
||||||
|
}
|
||||||
|
|
||||||
for _, ch := range changes {
|
for _, ch := range changes {
|
||||||
err = a.treeStorage.AddChange(ch)
|
err = a.treeStorage.AddChange(ch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -297,6 +362,7 @@ func (a *aclTree) AddChanges(ctx context.Context, changes ...*Change) (AddResult
|
|||||||
return AddResult{
|
return AddResult{
|
||||||
OldHeads: prevHeads,
|
OldHeads: prevHeads,
|
||||||
Heads: a.fullTree.Heads(),
|
Heads: a.fullTree.Heads(),
|
||||||
|
Added: getAddedChanges(),
|
||||||
Summary: AddResultSummaryRebuild,
|
Summary: AddResultSummaryRebuild,
|
||||||
}, nil
|
}, nil
|
||||||
default:
|
default:
|
||||||
@ -310,26 +376,21 @@ func (a *aclTree) AddChanges(ctx context.Context, changes ...*Change) (AddResult
|
|||||||
return AddResult{
|
return AddResult{
|
||||||
OldHeads: prevHeads,
|
OldHeads: prevHeads,
|
||||||
Heads: a.fullTree.Heads(),
|
Heads: a.fullTree.Heads(),
|
||||||
|
Added: getAddedChanges(),
|
||||||
Summary: AddResultSummaryAppend,
|
Summary: AddResultSummaryAppend,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclTree) Iterate(f func(change *Change) bool) {
|
func (a *aclTree) Iterate(f func(change *Change) bool) {
|
||||||
a.RLock()
|
|
||||||
defer a.RUnlock()
|
|
||||||
a.fullTree.Iterate(a.fullTree.RootId(), f)
|
a.fullTree.Iterate(a.fullTree.RootId(), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclTree) IterateFrom(s string, f func(change *Change) bool) {
|
func (a *aclTree) IterateFrom(s string, f func(change *Change) bool) {
|
||||||
a.RLock()
|
|
||||||
defer a.RUnlock()
|
|
||||||
a.fullTree.Iterate(s, f)
|
a.fullTree.Iterate(s, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclTree) HasChange(s string) bool {
|
func (a *aclTree) HasChange(s string) bool {
|
||||||
a.RLock()
|
|
||||||
defer a.RUnlock()
|
|
||||||
_, attachedExists := a.fullTree.attached[s]
|
_, attachedExists := a.fullTree.attached[s]
|
||||||
_, unattachedExists := a.fullTree.unAttached[s]
|
_, unattachedExists := a.fullTree.unAttached[s]
|
||||||
_, invalidExists := a.fullTree.invalidChanges[s]
|
_, invalidExists := a.fullTree.invalidChanges[s]
|
||||||
@ -337,13 +398,123 @@ func (a *aclTree) HasChange(s string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclTree) Heads() []string {
|
func (a *aclTree) Heads() []string {
|
||||||
a.RLock()
|
|
||||||
defer a.RUnlock()
|
|
||||||
return a.fullTree.Heads()
|
return a.fullTree.Heads()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclTree) Root() *Change {
|
func (a *aclTree) Root() *Change {
|
||||||
a.RLock()
|
|
||||||
defer a.RUnlock()
|
|
||||||
return a.fullTree.Root()
|
return a.fullTree.Root()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *aclTree) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclTree) SnapshotPath() []string {
|
||||||
|
// TODO: think about caching this
|
||||||
|
|
||||||
|
var path []string
|
||||||
|
// TODO: think that the user may have not all of the snapshots locally
|
||||||
|
currentSnapshotId := a.fullTree.RootId()
|
||||||
|
for currentSnapshotId != "" {
|
||||||
|
sn, err := a.treeBuilder.loadChange(currentSnapshotId)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
path = append(path, currentSnapshotId)
|
||||||
|
currentSnapshotId = sn.SnapshotId
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclTree) ChangesAfterCommonSnapshot(theirPath []string) ([]*aclpb.RawChange, error) {
|
||||||
|
// TODO: think about when the clients will have their full acl tree and thus full snapshots
|
||||||
|
// but no changes after some of the snapshots
|
||||||
|
|
||||||
|
var (
|
||||||
|
isNewDocument = len(theirPath) == 0
|
||||||
|
ourPath = a.SnapshotPath()
|
||||||
|
// by default returning everything we have
|
||||||
|
commonSnapshot = ourPath[len(ourPath)-1] // TODO: root snapshot, probably it is better to have a specific method in treestorage
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
// if this is non-empty request
|
||||||
|
if !isNewDocument {
|
||||||
|
commonSnapshot, err = a.commonSnapshotForTwoPaths(ourPath, theirPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var rawChanges []*aclpb.RawChange
|
||||||
|
// using custom load function to skip verification step and save raw changes
|
||||||
|
load := func(id string) (*Change, error) {
|
||||||
|
raw, err := a.treeStorage.GetChange(context.Background(), id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
aclChange, err := a.treeBuilder.makeUnverifiedACLChange(raw)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ch := NewChange(id, aclChange)
|
||||||
|
rawChanges = append(rawChanges, raw)
|
||||||
|
return ch, nil
|
||||||
|
}
|
||||||
|
// we presume that we have everything after the common snapshot, though this may not be the case in case of clients and only ACL tree changes
|
||||||
|
log.With(
|
||||||
|
zap.Strings("heads", a.fullTree.Heads()),
|
||||||
|
zap.String("breakpoint", commonSnapshot),
|
||||||
|
zap.String("id", a.id)).
|
||||||
|
Debug("getting all changes from common snapshot")
|
||||||
|
_, err = a.treeBuilder.dfs(a.fullTree.Heads(), commonSnapshot, load)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if isNewDocument {
|
||||||
|
// adding snapshot to raw changes
|
||||||
|
_, err = load(commonSnapshot)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.With(
|
||||||
|
zap.Int("len(changes)", len(rawChanges)),
|
||||||
|
zap.String("id", a.id)).
|
||||||
|
Debug("sending all changes after common snapshot")
|
||||||
|
|
||||||
|
return rawChanges, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclTree) DebugDump() (string, error) {
|
||||||
|
return a.fullTree.Graph()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclTree) commonSnapshotForTwoPaths(ourPath []string, theirPath []string) (string, error) {
|
||||||
|
var i int
|
||||||
|
var j int
|
||||||
|
log.With(zap.Strings("our path", ourPath), zap.Strings("their path", theirPath)).
|
||||||
|
Debug("finding common snapshot for two paths")
|
||||||
|
OuterLoop:
|
||||||
|
// find starting point from the right
|
||||||
|
for i = len(ourPath) - 1; i >= 0; i-- {
|
||||||
|
for j = len(theirPath) - 1; j >= 0; j-- {
|
||||||
|
// most likely there would be only one comparison, because mostly the snapshot path will start from the root for nodes
|
||||||
|
if ourPath[i] == theirPath[j] {
|
||||||
|
break OuterLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i < 0 || j < 0 {
|
||||||
|
return "", ErrNoCommonSnapshot
|
||||||
|
}
|
||||||
|
// find last common element of the sequence moving from right to left
|
||||||
|
for i >= 0 && j >= 0 {
|
||||||
|
if ourPath[i] == theirPath[j] {
|
||||||
|
i--
|
||||||
|
j--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ourPath[i+1], nil
|
||||||
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ func TestACLTree_UserJoinBuild(t *testing.T) {
|
|||||||
Identity: keychain.GetIdentity("A"),
|
Identity: keychain.GetIdentity("A"),
|
||||||
SignKey: keychain.SigningKeys["A"],
|
SignKey: keychain.SigningKeys["A"],
|
||||||
EncKey: keychain.EncryptionKeys["A"],
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
Decoder: signingkey.NewEd25519Decoder(),
|
Decoder: signingkey.NewEd25519PubKeyDecoder(),
|
||||||
}
|
}
|
||||||
listener := &mockListener{}
|
listener := &mockListener{}
|
||||||
tree, err := BuildACLTree(thr, accountData, listener)
|
tree, err := BuildACLTree(thr, accountData, listener)
|
||||||
@ -62,24 +62,16 @@ func TestACLTree_UserJoinUpdate_Append(t *testing.T) {
|
|||||||
Identity: keychain.GetIdentity("A"),
|
Identity: keychain.GetIdentity("A"),
|
||||||
SignKey: keychain.SigningKeys["A"],
|
SignKey: keychain.SigningKeys["A"],
|
||||||
EncKey: keychain.EncryptionKeys["A"],
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
Decoder: signingkey.NewEd25519Decoder(),
|
Decoder: signingkey.NewEd25519PubKeyDecoder(),
|
||||||
}
|
}
|
||||||
|
|
||||||
listener := &mockListener{}
|
listener := &mockListener{}
|
||||||
tree, err := BuildACLTree(thr, accountData, listener)
|
tree, err := BuildACLTree(thr, accountData, listener)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||||
}
|
}
|
||||||
rawChanges := thr.GetUpdates("append")
|
rawChanges := thr.GetUpdates("append")
|
||||||
var changes []*Change
|
res, err := tree.AddRawChanges(context.Background(), rawChanges...)
|
||||||
for _, ch := range rawChanges {
|
|
||||||
newCh, err := NewFromRawChange(ch)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("should be able to create change from raw: %v", err)
|
|
||||||
}
|
|
||||||
changes = append(changes, newCh)
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := tree.AddChanges(context.Background(), changes...)
|
|
||||||
assert.Equal(t, res.Summary, AddResultSummaryAppend)
|
assert.Equal(t, res.Summary, AddResultSummaryAppend)
|
||||||
|
|
||||||
aclState := tree.ACLState()
|
aclState := tree.ACLState()
|
||||||
@ -112,7 +104,7 @@ func TestACLTree_UserJoinUpdate_Rebuild(t *testing.T) {
|
|||||||
Identity: keychain.GetIdentity("A"),
|
Identity: keychain.GetIdentity("A"),
|
||||||
SignKey: keychain.SigningKeys["A"],
|
SignKey: keychain.SigningKeys["A"],
|
||||||
EncKey: keychain.EncryptionKeys["A"],
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
Decoder: signingkey.NewEd25519Decoder(),
|
Decoder: signingkey.NewEd25519PubKeyDecoder(),
|
||||||
}
|
}
|
||||||
listener := &mockListener{}
|
listener := &mockListener{}
|
||||||
tree, err := BuildACLTree(thr, accountData, listener)
|
tree, err := BuildACLTree(thr, accountData, listener)
|
||||||
@ -120,16 +112,7 @@ func TestACLTree_UserJoinUpdate_Rebuild(t *testing.T) {
|
|||||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||||
}
|
}
|
||||||
rawChanges := thr.GetUpdates("rebuild")
|
rawChanges := thr.GetUpdates("rebuild")
|
||||||
var changes []*Change
|
res, err := tree.AddRawChanges(context.Background(), rawChanges...)
|
||||||
for _, ch := range rawChanges {
|
|
||||||
newCh, err := NewFromRawChange(ch)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("should be able to create change from raw: %v", err)
|
|
||||||
}
|
|
||||||
changes = append(changes, newCh)
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := tree.AddChanges(context.Background(), changes...)
|
|
||||||
assert.Equal(t, res.Summary, AddResultSummaryRebuild)
|
assert.Equal(t, res.Summary, AddResultSummaryRebuild)
|
||||||
|
|
||||||
aclState := tree.ACLState()
|
aclState := tree.ACLState()
|
||||||
@ -163,7 +146,7 @@ func TestACLTree_UserRemoveBuild(t *testing.T) {
|
|||||||
Identity: keychain.GetIdentity("A"),
|
Identity: keychain.GetIdentity("A"),
|
||||||
SignKey: keychain.SigningKeys["A"],
|
SignKey: keychain.SigningKeys["A"],
|
||||||
EncKey: keychain.EncryptionKeys["A"],
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
Decoder: signingkey.NewEd25519Decoder(),
|
Decoder: signingkey.NewEd25519PubKeyDecoder(),
|
||||||
}
|
}
|
||||||
listener := &mockListener{}
|
listener := &mockListener{}
|
||||||
tree, err := BuildACLTree(thr, accountData, listener)
|
tree, err := BuildACLTree(thr, accountData, listener)
|
||||||
@ -194,7 +177,7 @@ func TestACLTree_UserRemoveBeforeBuild(t *testing.T) {
|
|||||||
Identity: keychain.GetIdentity("A"),
|
Identity: keychain.GetIdentity("A"),
|
||||||
SignKey: keychain.SigningKeys["A"],
|
SignKey: keychain.SigningKeys["A"],
|
||||||
EncKey: keychain.EncryptionKeys["A"],
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
Decoder: signingkey.NewEd25519Decoder(),
|
Decoder: signingkey.NewEd25519PubKeyDecoder(),
|
||||||
}
|
}
|
||||||
listener := &mockListener{}
|
listener := &mockListener{}
|
||||||
tree, err := BuildACLTree(thr, accountData, listener)
|
tree, err := BuildACLTree(thr, accountData, listener)
|
||||||
@ -226,7 +209,7 @@ func TestACLTree_InvalidSnapshotBuild(t *testing.T) {
|
|||||||
Identity: keychain.GetIdentity("A"),
|
Identity: keychain.GetIdentity("A"),
|
||||||
SignKey: keychain.SigningKeys["A"],
|
SignKey: keychain.SigningKeys["A"],
|
||||||
EncKey: keychain.EncryptionKeys["A"],
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
Decoder: signingkey.NewEd25519Decoder(),
|
Decoder: signingkey.NewEd25519PubKeyDecoder(),
|
||||||
}
|
}
|
||||||
listener := &mockListener{}
|
listener := &mockListener{}
|
||||||
tree, err := BuildACLTree(thr, accountData, listener)
|
tree, err := BuildACLTree(thr, accountData, listener)
|
||||||
@ -257,7 +240,7 @@ func TestACLTree_ValidSnapshotBuild(t *testing.T) {
|
|||||||
Identity: keychain.GetIdentity("A"),
|
Identity: keychain.GetIdentity("A"),
|
||||||
SignKey: keychain.SigningKeys["A"],
|
SignKey: keychain.SigningKeys["A"],
|
||||||
EncKey: keychain.EncryptionKeys["A"],
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
Decoder: signingkey.NewEd25519Decoder(),
|
Decoder: signingkey.NewEd25519PubKeyDecoder(),
|
||||||
}
|
}
|
||||||
listener := &mockListener{}
|
listener := &mockListener{}
|
||||||
tree, err := BuildACLTree(thr, accountData, listener)
|
tree, err := BuildACLTree(thr, accountData, listener)
|
||||||
|
|||||||
@ -2,17 +2,21 @@ package acltree
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||||
|
"github.com/gogo/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BuildTreeStorageWithACL(
|
func CreateNewTreeStorageWithACL(
|
||||||
acc *account.AccountData,
|
acc *account.AccountData,
|
||||||
build func(builder ChangeBuilder) error,
|
build func(builder ChangeBuilder) error,
|
||||||
create func(change *treestorage.RawChange) (treestorage.TreeStorage, error)) (treestorage.TreeStorage, error) {
|
create treestorage.CreatorFunc) (treestorage.TreeStorage, error) {
|
||||||
bld := newChangeBuilder()
|
bld := newChangeBuilder()
|
||||||
bld.Init(
|
bld.Init(
|
||||||
newACLState(acc.Identity, acc.EncKey, signingkey.NewEd25519Decoder()),
|
newACLState(acc.Identity, acc.EncKey, signingkey.NewEd25519PubKeyDecoder()),
|
||||||
&Tree{},
|
&Tree{},
|
||||||
acc)
|
acc)
|
||||||
err := build(bld)
|
err := build(bld)
|
||||||
@ -26,13 +30,17 @@ func BuildTreeStorageWithACL(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rawChange := &treestorage.RawChange{
|
rawChange := &aclpb.RawChange{
|
||||||
Payload: payload,
|
Payload: payload,
|
||||||
Signature: change.Signature(),
|
Signature: change.Signature(),
|
||||||
Id: change.CID(),
|
Id: change.CID(),
|
||||||
}
|
}
|
||||||
|
header, id, err := createTreeHeaderAndId(rawChange)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
thr, err := create(rawChange)
|
thr, err := create(id, header, []*aclpb.RawChange{rawChange})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -43,3 +51,20 @@ func BuildTreeStorageWithACL(
|
|||||||
}
|
}
|
||||||
return thr, nil
|
return thr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createTreeHeaderAndId(change *aclpb.RawChange) (*treepb.TreeHeader, string, error) {
|
||||||
|
header := &treepb.TreeHeader{
|
||||||
|
FirstChangeId: change.Id,
|
||||||
|
IsWorkspace: false,
|
||||||
|
}
|
||||||
|
marshalledHeader, err := proto.Marshal(header)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
treeId, err := cid.NewCIDFromBytes(marshalledHeader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return header, treeId, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ func Test_BuildTreeStorageWithACL(t *testing.T) {
|
|||||||
SignKey: keychain.SigningKeys["A"],
|
SignKey: keychain.SigningKeys["A"],
|
||||||
EncKey: keychain.EncryptionKeys["A"],
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
}
|
}
|
||||||
thr, err := BuildTreeStorageWithACL(
|
thr, err := CreateNewTreeStorageWithACL(
|
||||||
data,
|
data,
|
||||||
func(builder ChangeBuilder) error {
|
func(builder ChangeBuilder) error {
|
||||||
return builder.UserAdd(
|
return builder.UserAdd(
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package acltree
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
|
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
|
||||||
@ -47,7 +46,7 @@ func (ch *Change) IsACLChange() bool {
|
|||||||
return ch.Content.GetAclData() != nil
|
return ch.Content.GetAclData() != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFromRawChange(rawChange *treestorage.RawChange) (*Change, error) {
|
func NewFromRawChange(rawChange *aclpb.RawChange) (*Change, error) {
|
||||||
unmarshalled := &aclpb.ACLChange{}
|
unmarshalled := &aclpb.ACLChange{}
|
||||||
err := proto.Unmarshal(rawChange.Payload, unmarshalled)
|
err := proto.Unmarshal(rawChange.Payload, unmarshalled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -73,7 +73,7 @@ func (c *changeLoader) verify(identity string, payload, signature []byte) (isVer
|
|||||||
return identityKey.Verify(payload, signature)
|
return identityKey.Verify(payload, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *changeLoader) makeVerifiedACLChange(change *treestorage.RawChange) (aclChange *aclpb.ACLChange, err error) {
|
func (c *changeLoader) makeVerifiedACLChange(change *aclpb.RawChange) (aclChange *aclpb.ACLChange, err error) {
|
||||||
aclChange = new(aclpb.ACLChange)
|
aclChange = new(aclpb.ACLChange)
|
||||||
|
|
||||||
// TODO: think what should we do with such cases, because this can be used by attacker to break our Tree
|
// TODO: think what should we do with such cases, because this can be used by attacker to break our Tree
|
||||||
@ -91,3 +91,9 @@ func (c *changeLoader) makeVerifiedACLChange(change *treestorage.RawChange) (acl
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *changeLoader) makeUnverifiedACLChange(change *aclpb.RawChange) (aclChange *aclpb.ACLChange, err error) {
|
||||||
|
aclChange = new(aclpb.ACLChange)
|
||||||
|
err = proto.Unmarshal(change.Payload, aclChange)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import (
|
|||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||||
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -135,13 +134,16 @@ func (tb *treeBuilder) buildTree(heads []string, breakpoint string) (err error)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
tb.tree.AddFast(ch)
|
tb.tree.AddFast(ch)
|
||||||
changes, err := tb.dfs(heads, breakpoint)
|
changes, err := tb.dfs(heads, breakpoint, tb.loadChange)
|
||||||
|
|
||||||
tb.tree.AddFast(changes...)
|
tb.tree.AddFast(changes...)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tb *treeBuilder) dfs(heads []string, breakpoint string) (buf []*Change, err error) {
|
func (tb *treeBuilder) dfs(
|
||||||
|
heads []string,
|
||||||
|
breakpoint string,
|
||||||
|
load func(string) (*Change, error)) (buf []*Change, err error) {
|
||||||
stack := make([]string, len(heads), len(heads)*2)
|
stack := make([]string, len(heads), len(heads)*2)
|
||||||
copy(stack, heads)
|
copy(stack, heads)
|
||||||
|
|
||||||
@ -154,7 +156,7 @@ func (tb *treeBuilder) dfs(heads []string, breakpoint string) (buf []*Change, er
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
ch, err := tb.loadChange(id)
|
ch, err := load(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,6 +83,7 @@ func (t *Tree) Graph() (data string, err error) {
|
|||||||
// }
|
// }
|
||||||
// chSymbs = append(chSymbs, res)
|
// chSymbs = append(chSymbs, res)
|
||||||
//}
|
//}
|
||||||
|
chSymbs = append(chSymbs, "DEC")
|
||||||
}
|
}
|
||||||
|
|
||||||
shortId := c.Id
|
shortId := c.Id
|
||||||
|
|||||||
@ -17,6 +17,7 @@ type PlainTextDocument interface {
|
|||||||
AddText(ctx context.Context, text string) error
|
AddText(ctx context.Context, text string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this struct is not thread-safe, so use it wisely :-)
|
||||||
type plainTextDocument struct {
|
type plainTextDocument struct {
|
||||||
heads []string
|
heads []string
|
||||||
aclTree acltree.ACLTree
|
aclTree acltree.ACLTree
|
||||||
@ -117,7 +118,7 @@ func NewInMemoryPlainTextDocument(acc *account.AccountData, text string) (PlainT
|
|||||||
|
|
||||||
func NewPlainTextDocument(
|
func NewPlainTextDocument(
|
||||||
acc *account.AccountData,
|
acc *account.AccountData,
|
||||||
create func(change *treestorage.RawChange) (treestorage.TreeStorage, error),
|
create treestorage.CreatorFunc,
|
||||||
text string) (PlainTextDocument, error) {
|
text string) (PlainTextDocument, error) {
|
||||||
changeBuilder := func(builder acltree.ChangeBuilder) error {
|
changeBuilder := func(builder acltree.ChangeBuilder) error {
|
||||||
err := builder.UserAdd(acc.Identity, acc.EncKey.GetPublic(), aclpb.ACLChange_Admin)
|
err := builder.UserAdd(acc.Identity, acc.EncKey.GetPublic(), aclpb.ACLChange_Admin)
|
||||||
@ -127,7 +128,7 @@ func NewPlainTextDocument(
|
|||||||
builder.AddChangeContent(createInitialChangeContent(text))
|
builder.AddChangeContent(createInitialChangeContent(text))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
t, err := acltree.BuildTreeStorageWithACL(
|
t, err := acltree.CreateNewTreeStorageWithACL(
|
||||||
acc,
|
acc,
|
||||||
changeBuilder,
|
changeBuilder,
|
||||||
create)
|
create)
|
||||||
|
|||||||
@ -18,7 +18,7 @@ func TestDocument_NewPlainTextDocument(t *testing.T) {
|
|||||||
Identity: keychain.GetIdentity("A"),
|
Identity: keychain.GetIdentity("A"),
|
||||||
SignKey: keychain.SigningKeys["A"],
|
SignKey: keychain.SigningKeys["A"],
|
||||||
EncKey: keychain.EncryptionKeys["A"],
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
Decoder: signingkey.NewEd25519Decoder(),
|
Decoder: signingkey.NewEd25519PubKeyDecoder(),
|
||||||
}
|
}
|
||||||
|
|
||||||
doc, err := NewPlainTextDocument(data, treestorage.NewInMemoryTreeStorage, "Some text")
|
doc, err := NewPlainTextDocument(data, treestorage.NewInMemoryTreeStorage, "Some text")
|
||||||
@ -36,7 +36,7 @@ func TestDocument_PlainTextDocument_AddText(t *testing.T) {
|
|||||||
Identity: keychain.GetIdentity("A"),
|
Identity: keychain.GetIdentity("A"),
|
||||||
SignKey: keychain.SigningKeys["A"],
|
SignKey: keychain.SigningKeys["A"],
|
||||||
EncKey: keychain.EncryptionKeys["A"],
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
Decoder: signingkey.NewEd25519Decoder(),
|
Decoder: signingkey.NewEd25519PubKeyDecoder(),
|
||||||
}
|
}
|
||||||
|
|
||||||
doc, err := NewPlainTextDocument(data, treestorage.NewInMemoryTreeStorage, "Some text")
|
doc, err := NewPlainTextDocument(data, treestorage.NewInMemoryTreeStorage, "Some text")
|
||||||
|
|||||||
@ -32,7 +32,7 @@ func NewKeychain() *Keychain {
|
|||||||
GeneratedIdentities: map[string]string{},
|
GeneratedIdentities: map[string]string{},
|
||||||
ReadKeys: map[string]*SymKey{},
|
ReadKeys: map[string]*SymKey{},
|
||||||
ReadKeysByHash: map[uint64]*SymKey{},
|
ReadKeysByHash: map[uint64]*SymKey{},
|
||||||
coder: signingkey.NewEd25519Decoder(),
|
coder: signingkey.NewEd25519PubKeyDecoder(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import (
|
|||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||||
testpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb"
|
testpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/yamltests"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/yamltests"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
|
|
||||||
storagepb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
storagepb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||||
@ -87,7 +86,7 @@ func (t *TreeStorageBuilder) Heads() ([]string, error) {
|
|||||||
return t.heads, nil
|
return t.heads, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TreeStorageBuilder) AddRawChange(change *treestorage.RawChange) error {
|
func (t *TreeStorageBuilder) AddRawChange(change *aclpb.RawChange) error {
|
||||||
aclChange := new(aclpb.ACLChange)
|
aclChange := new(aclpb.ACLChange)
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -165,12 +164,12 @@ func (t *TreeStorageBuilder) RemoveOrphans(orphans ...string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TreeStorageBuilder) GetChange(ctx context.Context, recordID string) (*treestorage.RawChange, error) {
|
func (t *TreeStorageBuilder) GetChange(ctx context.Context, recordID string) (*aclpb.RawChange, error) {
|
||||||
return t.getChange(recordID, t.allChanges), nil
|
return t.getChange(recordID, t.allChanges), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TreeStorageBuilder) GetUpdates(useCase string) []*treestorage.RawChange {
|
func (t *TreeStorageBuilder) GetUpdates(useCase string) []*aclpb.RawChange {
|
||||||
var res []*treestorage.RawChange
|
var res []*aclpb.RawChange
|
||||||
update := t.updates[useCase]
|
update := t.updates[useCase]
|
||||||
for _, ch := range update.changes {
|
for _, ch := range update.changes {
|
||||||
rawCh := t.getChange(ch.id, update.changes)
|
rawCh := t.getChange(ch.id, update.changes)
|
||||||
@ -183,7 +182,7 @@ func (t *TreeStorageBuilder) Header() (*storagepb.TreeHeader, error) {
|
|||||||
return t.header, nil
|
return t.header, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TreeStorageBuilder) getChange(changeId string, m map[string]*treeChange) *treestorage.RawChange {
|
func (t *TreeStorageBuilder) getChange(changeId string, m map[string]*treeChange) *aclpb.RawChange {
|
||||||
rec := m[changeId]
|
rec := m[changeId]
|
||||||
|
|
||||||
if rec.changesDataDecrypted != nil {
|
if rec.changesDataDecrypted != nil {
|
||||||
@ -205,7 +204,7 @@ func (t *TreeStorageBuilder) getChange(changeId string, m map[string]*treeChange
|
|||||||
panic("should be able to sign final acl message!")
|
panic("should be able to sign final acl message!")
|
||||||
}
|
}
|
||||||
|
|
||||||
transformedRec := &treestorage.RawChange{
|
transformedRec := &aclpb.RawChange{
|
||||||
Payload: aclMarshaled,
|
Payload: aclMarshaled,
|
||||||
Signature: signature,
|
Signature: signature,
|
||||||
Id: changeId,
|
Id: changeId,
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
"sync"
|
"sync"
|
||||||
@ -16,34 +16,30 @@ type inMemoryTreeStorage struct {
|
|||||||
header *treepb.TreeHeader
|
header *treepb.TreeHeader
|
||||||
heads []string
|
heads []string
|
||||||
orphans []string
|
orphans []string
|
||||||
changes map[string]*RawChange
|
changes map[string]*aclpb.RawChange
|
||||||
|
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInMemoryTreeStorage(firstChange *RawChange) (TreeStorage, error) {
|
type CreatorFunc = func(string, *treepb.TreeHeader, []*aclpb.RawChange) (TreeStorage, error)
|
||||||
header := &treepb.TreeHeader{
|
|
||||||
FirstChangeId: firstChange.Id,
|
|
||||||
IsWorkspace: false,
|
|
||||||
}
|
|
||||||
marshalledHeader, err := proto.Marshal(header)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
treeId, err := cid.NewCIDFromBytes(marshalledHeader)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
changes := make(map[string]*RawChange)
|
func NewInMemoryTreeStorage(
|
||||||
changes[firstChange.Id] = firstChange
|
treeId string,
|
||||||
|
header *treepb.TreeHeader,
|
||||||
|
changes []*aclpb.RawChange) (TreeStorage, error) {
|
||||||
|
allChanges := make(map[string]*aclpb.RawChange)
|
||||||
|
var orphans []string
|
||||||
|
for _, ch := range changes {
|
||||||
|
allChanges[ch.Id] = ch
|
||||||
|
orphans = append(orphans, ch.Id)
|
||||||
|
}
|
||||||
|
|
||||||
return &inMemoryTreeStorage{
|
return &inMemoryTreeStorage{
|
||||||
id: treeId,
|
id: treeId,
|
||||||
header: header,
|
header: header,
|
||||||
heads: []string{firstChange.Id},
|
heads: nil,
|
||||||
orphans: nil,
|
orphans: orphans,
|
||||||
changes: changes,
|
changes: allChanges,
|
||||||
RWMutex: sync.RWMutex{},
|
RWMutex: sync.RWMutex{},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -97,7 +93,7 @@ func (t *inMemoryTreeStorage) AddOrphans(orphans ...string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *inMemoryTreeStorage) AddRawChange(change *RawChange) error {
|
func (t *inMemoryTreeStorage) AddRawChange(change *aclpb.RawChange) error {
|
||||||
t.Lock()
|
t.Lock()
|
||||||
defer t.Unlock()
|
defer t.Unlock()
|
||||||
// TODO: better to do deep copy
|
// TODO: better to do deep copy
|
||||||
@ -116,7 +112,7 @@ func (t *inMemoryTreeStorage) AddChange(change aclchanges.Change) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rawChange := &RawChange{
|
rawChange := &aclpb.RawChange{
|
||||||
Payload: fullMarshalledChange,
|
Payload: fullMarshalledChange,
|
||||||
Signature: signature,
|
Signature: signature,
|
||||||
Id: id,
|
Id: id,
|
||||||
@ -125,7 +121,7 @@ func (t *inMemoryTreeStorage) AddChange(change aclchanges.Change) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *inMemoryTreeStorage) GetChange(ctx context.Context, changeId string) (*RawChange, error) {
|
func (t *inMemoryTreeStorage) GetChange(ctx context.Context, changeId string) (*aclpb.RawChange, error) {
|
||||||
t.RLock()
|
t.RLock()
|
||||||
defer t.RUnlock()
|
defer t.RUnlock()
|
||||||
if res, exists := t.changes[changeId]; exists {
|
if res, exists := t.changes[changeId]; exists {
|
||||||
@ -133,3 +129,35 @@ func (t *inMemoryTreeStorage) GetChange(ctx context.Context, changeId string) (*
|
|||||||
}
|
}
|
||||||
return nil, fmt.Errorf("could not get change with id: %s", changeId)
|
return nil, fmt.Errorf("could not get change with id: %s", changeId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type inMemoryTreeStorageProvider struct {
|
||||||
|
trees map[string]TreeStorage
|
||||||
|
sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *inMemoryTreeStorageProvider) TreeStorage(treeId string) (TreeStorage, error) {
|
||||||
|
i.RLock()
|
||||||
|
defer i.RUnlock()
|
||||||
|
if tree, exists := i.trees[treeId]; exists {
|
||||||
|
return tree, nil
|
||||||
|
}
|
||||||
|
return nil, ErrUnknownTreeId
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *inMemoryTreeStorageProvider) CreateTreeStorage(treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange) (TreeStorage, error) {
|
||||||
|
i.Lock()
|
||||||
|
defer i.Unlock()
|
||||||
|
res, err := NewInMemoryTreeStorage(treeId, header, changes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
i.trees[treeId] = res
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInMemoryTreeStorageProvider() Provider {
|
||||||
|
return &inMemoryTreeStorageProvider{
|
||||||
|
trees: make(map[string]TreeStorage),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
14
pkg/acl/treestorage/provider.go
Normal file
14
pkg/acl/treestorage/provider.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package treestorage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrUnknownTreeId = errors.New("tree does not exist")
|
||||||
|
|
||||||
|
type Provider interface {
|
||||||
|
TreeStorage(treeId string) (TreeStorage, error)
|
||||||
|
CreateTreeStorage(treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange) (TreeStorage, error)
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ package treestorage
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,15 +17,9 @@ type TreeStorage interface {
|
|||||||
RemoveOrphans(orphan ...string) error
|
RemoveOrphans(orphan ...string) error
|
||||||
AddOrphans(orphan ...string) error
|
AddOrphans(orphan ...string) error
|
||||||
|
|
||||||
AddRawChange(change *RawChange) error
|
AddRawChange(change *aclpb.RawChange) error
|
||||||
AddChange(change aclchanges.Change) error
|
AddChange(change aclchanges.Change) error
|
||||||
|
|
||||||
// TODO: have methods with raw changes also
|
// TODO: have methods with raw changes also
|
||||||
GetChange(ctx context.Context, recordID string) (*RawChange, error)
|
GetChange(ctx context.Context, recordID string) (*aclpb.RawChange, error)
|
||||||
}
|
|
||||||
|
|
||||||
type RawChange struct {
|
|
||||||
Payload []byte
|
|
||||||
Signature []byte
|
|
||||||
Id string
|
|
||||||
}
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
package anytype;
|
package tree;
|
||||||
option go_package = "treepb";
|
option go_package = "treepb";
|
||||||
|
|
||||||
message TreeHeader {
|
message TreeHeader {
|
||||||
|
|||||||
@ -75,7 +75,7 @@ func (m *TreeHeader) GetIsWorkspace() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
proto.RegisterType((*TreeHeader)(nil), "anytype.TreeHeader")
|
proto.RegisterType((*TreeHeader)(nil), "tree.TreeHeader")
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -83,18 +83,18 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptor_e7d760b855878644 = []byte{
|
var fileDescriptor_e7d760b855878644 = []byte{
|
||||||
// 170 bytes of a gzipped FileDescriptorProto
|
// 165 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x29, 0xc8, 0x4e, 0xd7,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x29, 0xc8, 0x4e, 0xd7,
|
||||||
0x4f, 0x4c, 0xce, 0xd1, 0x2f, 0x29, 0x4a, 0x4d, 0x2d, 0x2e, 0xc9, 0x2f, 0x4a, 0x4c, 0x4f, 0x05,
|
0x4f, 0x4c, 0xce, 0xd1, 0x2f, 0x29, 0x4a, 0x4d, 0x2d, 0x2e, 0xc9, 0x2f, 0x4a, 0x4c, 0x4f, 0x05,
|
||||||
0xb3, 0x0b, 0x92, 0xf4, 0x0b, 0x8a, 0xf2, 0x4b, 0xf2, 0x8b, 0xc1, 0x3c, 0x3d, 0x30, 0x5b, 0x88,
|
0xb3, 0x0b, 0x92, 0xf4, 0x0b, 0x8a, 0xf2, 0x4b, 0xf2, 0x8b, 0xc1, 0x3c, 0x3d, 0x30, 0x5b, 0x88,
|
||||||
0x3d, 0x31, 0xaf, 0xb2, 0xa4, 0xb2, 0x20, 0x55, 0x29, 0x84, 0x8b, 0x2b, 0xa4, 0x28, 0x35, 0xd5,
|
0x05, 0xc4, 0x56, 0x0a, 0xe1, 0xe2, 0x0a, 0x29, 0x4a, 0x4d, 0xf5, 0x48, 0x4d, 0x4c, 0x49, 0x2d,
|
||||||
0x23, 0x35, 0x31, 0x25, 0xb5, 0x48, 0x48, 0x85, 0x8b, 0x37, 0x2d, 0xb3, 0xa8, 0xb8, 0xc4, 0x39,
|
0x12, 0x52, 0xe1, 0xe2, 0x4d, 0xcb, 0x2c, 0x2a, 0x2e, 0x71, 0xce, 0x48, 0xcc, 0x4b, 0x4f, 0xf5,
|
||||||
0x23, 0x31, 0x2f, 0x3d, 0xd5, 0x33, 0x45, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, 0x55, 0x50,
|
0x4c, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x42, 0x15, 0x14, 0x52, 0xe0, 0xe2, 0xce, 0x2c,
|
||||||
0x48, 0x81, 0x8b, 0x3b, 0xb3, 0x38, 0x3c, 0xbf, 0x28, 0xbb, 0xb8, 0x20, 0x31, 0x39, 0x55, 0x82,
|
0x0e, 0xcf, 0x2f, 0xca, 0x2e, 0x2e, 0x48, 0x4c, 0x4e, 0x95, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x08,
|
||||||
0x49, 0x81, 0x51, 0x83, 0x23, 0x08, 0x59, 0xc8, 0x49, 0xe1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f,
|
0x42, 0x16, 0x72, 0x52, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4,
|
||||||
0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b,
|
0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0x36,
|
||||||
0x8f, 0xe5, 0x18, 0xa2, 0xd8, 0x20, 0x4e, 0x4a, 0x62, 0x03, 0xbb, 0xc3, 0x18, 0x10, 0x00, 0x00,
|
0x88, 0x7b, 0x92, 0xd8, 0xc0, 0x8e, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x09, 0x4f, 0xc6,
|
||||||
0xff, 0xff, 0xb1, 0x3f, 0x66, 0x17, 0xb7, 0x00, 0x00, 0x00,
|
0xec, 0xb4, 0x00, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *TreeHeader) Marshal() (dAtA []byte, err error) {
|
func (m *TreeHeader) Marshal() (dAtA []byte, err error) {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ var (
|
|||||||
ErrClosed = errors.New("object cache closed")
|
ErrClosed = errors.New("object cache closed")
|
||||||
ErrExists = errors.New("object exists")
|
ErrExists = errors.New("object exists")
|
||||||
ErrTimeout = errors.New("loading object timed out")
|
ErrTimeout = errors.New("loading object timed out")
|
||||||
|
ErrNotExists = errors.New("object not exists")
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -20,10 +21,6 @@ var (
|
|||||||
defaultGC = 20 * time.Second
|
defaultGC = 20 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
type key int
|
|
||||||
|
|
||||||
const CacheTimeout key = 0
|
|
||||||
|
|
||||||
var log = logger.NewNamed("ocache")
|
var log = logger.NewNamed("ocache")
|
||||||
|
|
||||||
type LoadFunc func(ctx context.Context, id string) (value Object, err error)
|
type LoadFunc func(ctx context.Context, id string) (value Object, err error)
|
||||||
@ -61,7 +58,9 @@ func New(loadFunc LoadFunc, opts ...Option) OCache {
|
|||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(c)
|
o(c)
|
||||||
}
|
}
|
||||||
|
if c.ttl != 0 {
|
||||||
go c.ticker()
|
go c.ticker()
|
||||||
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,6 +98,8 @@ type OCache interface {
|
|||||||
// Increases the object refs counter on successful
|
// Increases the object refs counter on successful
|
||||||
// When 'loadFunc' returns a non-nil error, an object will not be stored to cache
|
// When 'loadFunc' returns a non-nil error, an object will not be stored to cache
|
||||||
Get(ctx context.Context, id string) (value Object, err error)
|
Get(ctx context.Context, id string) (value Object, err error)
|
||||||
|
// Pick returns value if it's presents in cache (will not call loadFunc)
|
||||||
|
Pick(id string) (value Object, err error)
|
||||||
// Add adds new object to cache
|
// Add adds new object to cache
|
||||||
// Returns error when object exists
|
// Returns error when object exists
|
||||||
Add(id string, value Object) (err error)
|
Add(id string, value Object) (err error)
|
||||||
@ -154,26 +155,26 @@ func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) {
|
|||||||
e.refCount++
|
e.refCount++
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
|
|
||||||
timeout := ctx.Value(CacheTimeout)
|
|
||||||
if load {
|
if load {
|
||||||
if timeout != nil {
|
|
||||||
go c.load(ctx, id, e)
|
go c.load(ctx, id, e)
|
||||||
} else {
|
|
||||||
c.load(ctx, id, e)
|
|
||||||
}
|
}
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
case <-e.load:
|
||||||
|
}
|
||||||
|
return e.value, e.loadErr
|
||||||
}
|
}
|
||||||
|
|
||||||
if timeout != nil {
|
func (c *oCache) Pick(id string) (value Object, err error) {
|
||||||
duration := timeout.(time.Duration)
|
c.mu.Lock()
|
||||||
select {
|
val, ok := c.data[id]
|
||||||
case <-e.load:
|
c.mu.Unlock()
|
||||||
return e.value, e.loadErr
|
if !ok {
|
||||||
case <-time.After(duration):
|
return nil, ErrNotExists
|
||||||
return nil, ErrTimeout
|
|
||||||
}
|
}
|
||||||
}
|
<-val.load
|
||||||
<-e.load
|
return val.value, val.loadErr
|
||||||
return e.value, e.loadErr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *oCache) load(ctx context.Context, id string, e *entry) {
|
func (c *oCache) load(ctx context.Context, id string, e *entry) {
|
||||||
|
|||||||
@ -92,6 +92,20 @@ func TestOCache_Get(t *testing.T) {
|
|||||||
_, err := c.Get(context.TODO(), "id")
|
_, err := c.Get(context.TODO(), "id")
|
||||||
assert.Equal(t, ErrClosed, err)
|
assert.Equal(t, ErrClosed, err)
|
||||||
})
|
})
|
||||||
|
t.Run("context cancel", func(t *testing.T) {
|
||||||
|
c := New(func(ctx context.Context, id string) (value Object, err error) {
|
||||||
|
time.Sleep(time.Second / 3)
|
||||||
|
return &testObject{
|
||||||
|
name: "id",
|
||||||
|
}, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
cancel()
|
||||||
|
_, err := c.Get(ctx, "id")
|
||||||
|
assert.Equal(t, context.Canceled, err)
|
||||||
|
assert.NoError(t, c.Close())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOCache_GC(t *testing.T) {
|
func TestOCache_GC(t *testing.T) {
|
||||||
|
|||||||
73
service/account/service.go
Normal file
73
service/account/service.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/config"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||||
|
)
|
||||||
|
|
||||||
|
const CName = "account"
|
||||||
|
|
||||||
|
type Service interface {
|
||||||
|
Account() *account.AccountData
|
||||||
|
}
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
accountData *account.AccountData
|
||||||
|
peerId string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Account() *account.AccountData {
|
||||||
|
return s.accountData
|
||||||
|
}
|
||||||
|
|
||||||
|
type StaticAccount struct {
|
||||||
|
SigningKey string `yaml:"signingKey"`
|
||||||
|
EncryptionKey string `yaml:"encryptionKey"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() app.Component {
|
||||||
|
return &service{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
cfg := a.MustComponent(config.CName).(*config.Config)
|
||||||
|
|
||||||
|
// decoding our keys
|
||||||
|
privateEncryptionDecoder := encryptionkey.NewRSAPrivKeyDecoder()
|
||||||
|
privateSigningDecoder := signingkey.NewEDPrivKeyDecoder()
|
||||||
|
publicSigningDecoder := signingkey.NewEDPubKeyDecoder()
|
||||||
|
acc := cfg.Account
|
||||||
|
|
||||||
|
decodedEncryptionKey, err := privateEncryptionDecoder.DecodeFromString(acc.EncryptionKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
decodedSigningKey, err := privateSigningDecoder.DecodeFromString(acc.SigningKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
signKey := decodedSigningKey.(signingkey.PrivKey)
|
||||||
|
identity, err := publicSigningDecoder.EncodeToString(signKey.GetPublic())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: using acl lib format basically, but we should simplify this
|
||||||
|
s.accountData = &account.AccountData{
|
||||||
|
Identity: identity,
|
||||||
|
SignKey: signKey,
|
||||||
|
EncKey: decodedEncryptionKey.(encryptionkey.PrivKey),
|
||||||
|
Decoder: signingkey.NewEd25519PubKeyDecoder(),
|
||||||
|
}
|
||||||
|
s.peerId = acc.PeerId
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Name() (name string) {
|
||||||
|
return CName
|
||||||
|
}
|
||||||
135
service/api/service.go
Normal file
135
service/api/service.go
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/config"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/document"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/treecache"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const CName = "APIService"
|
||||||
|
|
||||||
|
var log = logger.NewNamed("api")
|
||||||
|
|
||||||
|
func New() app.Component {
|
||||||
|
return &service{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
treeCache treecache.Service
|
||||||
|
documentService document.Service
|
||||||
|
srv *http.Server
|
||||||
|
cfg *config.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
s.treeCache = a.MustComponent(treecache.CName).(treecache.Service)
|
||||||
|
s.documentService = a.MustComponent(document.CName).(document.Service)
|
||||||
|
s.cfg = a.MustComponent(config.CName).(*config.Config)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Name() (name string) {
|
||||||
|
return CName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Run(ctx context.Context) (err error) {
|
||||||
|
defer func() {
|
||||||
|
if err == nil {
|
||||||
|
log.With(zap.String("port", s.cfg.APIServer.Port)).Info("api server started running")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
s.srv = &http.Server{
|
||||||
|
Addr: fmt.Sprintf(":%s", s.cfg.APIServer.Port),
|
||||||
|
}
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("/treeDump", s.treeDump)
|
||||||
|
mux.HandleFunc("/createDocument", s.createDocument)
|
||||||
|
mux.HandleFunc("/appendDocument", s.appendDocument)
|
||||||
|
s.srv.Handler = mux
|
||||||
|
|
||||||
|
go s.runServer()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) runServer() {
|
||||||
|
err := s.srv.ListenAndServe()
|
||||||
|
if err != nil {
|
||||||
|
log.With(zap.Error(err)).Error("could not run api server")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Close(ctx context.Context) (err error) {
|
||||||
|
return s.srv.Shutdown(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) treeDump(w http.ResponseWriter, req *http.Request) {
|
||||||
|
var (
|
||||||
|
query = req.URL.Query()
|
||||||
|
treeId = query.Get("treeId")
|
||||||
|
dump string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
err = s.treeCache.Do(context.Background(), treeId, func(tree acltree.ACLTree) error {
|
||||||
|
dump, err = tree.DebugDump()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
sendText(w, http.StatusInternalServerError, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sendText(w, http.StatusOK, dump)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) createDocument(w http.ResponseWriter, req *http.Request) {
|
||||||
|
var (
|
||||||
|
query = req.URL.Query()
|
||||||
|
text = query.Get("text")
|
||||||
|
)
|
||||||
|
timeoutCtx, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
||||||
|
treeId, err := s.documentService.CreateDocument(timeoutCtx, fmt.Sprintf("created document with id: %s", text))
|
||||||
|
cancel()
|
||||||
|
if err != nil {
|
||||||
|
sendText(w, http.StatusInternalServerError, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sendText(w, http.StatusOK, treeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) appendDocument(w http.ResponseWriter, req *http.Request) {
|
||||||
|
var (
|
||||||
|
query = req.URL.Query()
|
||||||
|
text = query.Get("text")
|
||||||
|
treeId = query.Get("treeId")
|
||||||
|
)
|
||||||
|
timeoutCtx, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
||||||
|
err := s.documentService.UpdateDocument(timeoutCtx, treeId, text)
|
||||||
|
cancel()
|
||||||
|
if err != nil {
|
||||||
|
sendText(w, http.StatusInternalServerError, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sendText(w, http.StatusOK, fmt.Sprintf("updated document with id: %s with text: %s", treeId, text))
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendText(r http.ResponseWriter, code int, body string) {
|
||||||
|
r.Header().Set("Content-Type", "text/plain")
|
||||||
|
r.WriteHeader(code)
|
||||||
|
|
||||||
|
_, err := io.WriteString(r, fmt.Sprintf("%s\n", body))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("writing response failed", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
84
service/example/example.go
Normal file
84
service/example/example.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package example
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/config"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var log = logger.NewNamed("example")
|
||||||
|
|
||||||
|
type Example struct {
|
||||||
|
pool pool.Pool
|
||||||
|
peerConf config.PeerList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Example) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
e.pool = a.MustComponent(pool.CName).(pool.Pool)
|
||||||
|
e.peerConf = a.MustComponent(config.CName).(*config.Config).PeerList
|
||||||
|
|
||||||
|
// subscribe for sync messages
|
||||||
|
e.pool.AddHandler(syncproto.MessageType_MessageTypeSync, e.syncHandler)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Example) Name() (name string) {
|
||||||
|
return "example"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Example) Run(ctx context.Context) (err error) {
|
||||||
|
// dial manually with all peers
|
||||||
|
for _, rp := range e.peerConf.Remote {
|
||||||
|
if er := e.pool.DialAndAddPeer(ctx, rp.PeerId); er != nil {
|
||||||
|
log.Info("can't dial to peer", zap.Error(er))
|
||||||
|
} else {
|
||||||
|
log.Info("connected with peer", zap.String("peerId", rp.PeerId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
go e.doRequests()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Example) syncHandler(ctx context.Context, msg *pool.Message) (err error) {
|
||||||
|
data := string(msg.Data) // you need unmarshal this bytes
|
||||||
|
log.Info("msg received", zap.String("peerId", msg.Peer().Id()), zap.String("data", data))
|
||||||
|
|
||||||
|
if strings.HasPrefix(data, "ack:") {
|
||||||
|
if err = msg.Ack(); err != nil {
|
||||||
|
log.Error("ack error", zap.Error(err))
|
||||||
|
}
|
||||||
|
} else if strings.HasPrefix(data, "ackErr:") {
|
||||||
|
if err = msg.AckError(42, "ack error description"); err != nil {
|
||||||
|
log.Error("ackErr error", zap.Error(err))
|
||||||
|
}
|
||||||
|
} else if strings.HasPrefix(data, "reply:") {
|
||||||
|
if err = msg.Reply([]byte("reply for:" + strings.TrimPrefix(data, "reply:"))); err != nil {
|
||||||
|
log.Error("reply error", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Example) doRequests() {
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
st := time.Now()
|
||||||
|
err := e.pool.SendAndWait(ctx, e.peerConf.Remote[0].PeerId, &syncproto.Message{
|
||||||
|
Header: &syncproto.Header{Type: syncproto.MessageType_MessageTypeSync},
|
||||||
|
Data: []byte("ack: something"),
|
||||||
|
})
|
||||||
|
log.Info("sent with ack:", zap.Error(err), zap.Duration("dur", time.Since(st)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Example) Close(ctx context.Context) (err error) {
|
||||||
|
return
|
||||||
|
}
|
||||||
104
service/net/dialer/dialer.go
Normal file
104
service/net/dialer/dialer.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package dialer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/config"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/rpc"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/secure"
|
||||||
|
"github.com/libp2p/go-libp2p-core/sec"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"net"
|
||||||
|
"storj.io/drpc"
|
||||||
|
"storj.io/drpc/drpcconn"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const CName = "net/dialer"
|
||||||
|
|
||||||
|
var ErrArrdsNotFound = errors.New("addrs for peer not found")
|
||||||
|
|
||||||
|
var log = logger.NewNamed(CName)
|
||||||
|
|
||||||
|
func New() Dialer {
|
||||||
|
return &dialer{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Dialer interface {
|
||||||
|
Dial(ctx context.Context, peerId string) (peer peer.Peer, err error)
|
||||||
|
UpdateAddrs(addrs map[string][]string)
|
||||||
|
app.Component
|
||||||
|
}
|
||||||
|
|
||||||
|
type dialer struct {
|
||||||
|
transport secure.Service
|
||||||
|
peerAddrs map[string][]string
|
||||||
|
|
||||||
|
mu sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dialer) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
d.transport = a.MustComponent(secure.CName).(secure.Service)
|
||||||
|
nodes := a.MustComponent(config.CName).(*config.Config).Nodes
|
||||||
|
d.peerAddrs = map[string][]string{}
|
||||||
|
for _, n := range nodes {
|
||||||
|
d.peerAddrs[n.PeerId] = []string{n.Address}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dialer) Name() (name string) {
|
||||||
|
return CName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dialer) UpdateAddrs(addrs map[string][]string) {
|
||||||
|
d.mu.Lock()
|
||||||
|
d.peerAddrs = addrs
|
||||||
|
d.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dialer) Dial(ctx context.Context, peerId string) (peer peer.Peer, err error) {
|
||||||
|
d.mu.RLock()
|
||||||
|
defer d.mu.RUnlock()
|
||||||
|
addrs, ok := d.peerAddrs[peerId]
|
||||||
|
if !ok || len(addrs) == 0 {
|
||||||
|
return nil, ErrArrdsNotFound
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
stream drpc.Stream
|
||||||
|
sc sec.SecureConn
|
||||||
|
)
|
||||||
|
for _, addr := range addrs {
|
||||||
|
stream, sc, err = d.makeStream(ctx, addr)
|
||||||
|
if err != nil {
|
||||||
|
log.Info("can't connect to host", zap.String("addr", addr))
|
||||||
|
} else {
|
||||||
|
err = nil
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return rpc.PeerFromStream(sc, stream, false), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dialer) makeStream(ctx context.Context, addr string) (stream drpc.Stream, sc sec.SecureConn, err error) {
|
||||||
|
tcpConn, err := net.Dial("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sc, err = d.transport.TLSConn(ctx, tcpConn)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Info("connected with remote host", zap.String("serverPeer", sc.RemotePeer().String()), zap.String("per", sc.LocalPeer().String()))
|
||||||
|
stream, err = drpcconn.New(sc).NewStream(ctx, "", rpc.Encoding)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return stream, sc, err
|
||||||
|
}
|
||||||
35
service/net/peer/peer.go
Normal file
35
service/net/peer/peer.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package peer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Dir uint
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DirInbound indicates peer created connection
|
||||||
|
DirInbound Dir = iota
|
||||||
|
// DirOutbound indicates that our host created connection
|
||||||
|
DirOutbound
|
||||||
|
)
|
||||||
|
|
||||||
|
type Info struct {
|
||||||
|
Id string
|
||||||
|
Dir Dir
|
||||||
|
LastActiveUnix int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i Info) LastActive() time.Time {
|
||||||
|
return time.Unix(i.LastActiveUnix, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Peer interface {
|
||||||
|
Id() string
|
||||||
|
Info() Info
|
||||||
|
Recv() (*syncproto.Message, error)
|
||||||
|
Send(msg *syncproto.Message) (err error)
|
||||||
|
Context() context.Context
|
||||||
|
Close() error
|
||||||
|
}
|
||||||
73
service/net/pool/message.go
Normal file
73
service/net/pool/message.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package pool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"gopkg.in/mgo.v2/bson"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
*syncproto.Message
|
||||||
|
peer peer.Peer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) Peer() peer.Peer {
|
||||||
|
return m.peer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) Reply(data []byte) (err error) {
|
||||||
|
rep := &syncproto.Message{
|
||||||
|
Header: &syncproto.Header{
|
||||||
|
TraceId: m.GetHeader().TraceId,
|
||||||
|
ReplyId: m.GetHeader().RequestId,
|
||||||
|
Type: syncproto.MessageType_MessageTypeSync,
|
||||||
|
},
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
return m.peer.Send(rep)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) Ack() (err error) {
|
||||||
|
ack := &syncproto.System{
|
||||||
|
Ack: &syncproto.SystemAck{},
|
||||||
|
}
|
||||||
|
data, err := ack.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rep := &syncproto.Message{
|
||||||
|
Header: &syncproto.Header{
|
||||||
|
TraceId: m.GetHeader().TraceId,
|
||||||
|
ReplyId: m.GetHeader().RequestId,
|
||||||
|
Type: syncproto.MessageType_MessageTypeSystem,
|
||||||
|
},
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
log.With(zap.String("header", rep.Header.String())).Info("sending ack to peer")
|
||||||
|
return m.peer.Send(rep)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) AckError(code syncproto.SystemErrorCode, description string) (err error) {
|
||||||
|
ack := &syncproto.System{
|
||||||
|
Ack: &syncproto.SystemAck{
|
||||||
|
Error: &syncproto.SystemError{
|
||||||
|
Code: code,
|
||||||
|
Description: description,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
data, err := ack.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rep := &syncproto.Message{
|
||||||
|
Header: &syncproto.Header{
|
||||||
|
TraceId: []byte(bson.NewObjectId()),
|
||||||
|
ReplyId: m.GetHeader().RequestId,
|
||||||
|
Type: syncproto.MessageType_MessageTypeSystem,
|
||||||
|
},
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
return m.peer.Send(rep)
|
||||||
|
}
|
||||||
28
service/net/pool/peer.go
Normal file
28
service/net/pool/peer.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package pool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
type peerEntry struct {
|
||||||
|
peer peer.Peer
|
||||||
|
groupIds []string
|
||||||
|
ready chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pe *peerEntry) addGroup(groupId string) (ok bool) {
|
||||||
|
if slice.FindPos(pe.groupIds, groupId) != -1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
pe.groupIds = append(pe.groupIds, groupId)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pe *peerEntry) removeGroup(groupId string) (ok bool) {
|
||||||
|
if slice.FindPos(pe.groupIds, groupId) == -1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
pe.groupIds = slice.Remove(pe.groupIds, groupId)
|
||||||
|
return true
|
||||||
|
}
|
||||||
329
service/net/pool/pool.go
Normal file
329
service/net/pool/pool.go
Normal file
@ -0,0 +1,329 @@
|
|||||||
|
package pool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/dialer"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CName = "sync/peerPool"
|
||||||
|
maxSimultaneousOperationsPerStream = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
var log = logger.NewNamed("peerPool")
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrPoolClosed = errors.New("peer pool is closed")
|
||||||
|
ErrPeerNotFound = errors.New("peer not found")
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewPool() Pool {
|
||||||
|
return &pool{closed: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Handler func(ctx context.Context, msg *Message) (err error)
|
||||||
|
|
||||||
|
type Pool interface {
|
||||||
|
DialAndAddPeer(ctx context.Context, id string) (err error)
|
||||||
|
AddAndReadPeer(peer peer.Peer) (err error)
|
||||||
|
AddHandler(msgType syncproto.MessageType, h Handler)
|
||||||
|
AddPeerIdToGroup(peerId, groupId string) (err error)
|
||||||
|
RemovePeerIdFromGroup(peerId, groupId string) (err error)
|
||||||
|
|
||||||
|
SendAndWait(ctx context.Context, peerId string, msg *syncproto.Message) (err error)
|
||||||
|
Broadcast(ctx context.Context, groupId string, msg *syncproto.Message) (err error)
|
||||||
|
|
||||||
|
app.ComponentRunnable
|
||||||
|
}
|
||||||
|
|
||||||
|
type pool struct {
|
||||||
|
peersById map[string]*peerEntry
|
||||||
|
waiters *waiters
|
||||||
|
handlers map[syncproto.MessageType][]Handler
|
||||||
|
peersIdsByGroup map[string][]string
|
||||||
|
|
||||||
|
dialer dialer.Dialer
|
||||||
|
|
||||||
|
closed bool
|
||||||
|
mu sync.RWMutex
|
||||||
|
wg *sync.WaitGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
p.peersById = map[string]*peerEntry{}
|
||||||
|
p.handlers = map[syncproto.MessageType][]Handler{}
|
||||||
|
p.peersIdsByGroup = map[string][]string{}
|
||||||
|
p.waiters = &waiters{waiters: map[uint64]*waiter{}}
|
||||||
|
p.dialer = a.MustComponent(dialer.CName).(dialer.Dialer)
|
||||||
|
p.wg = &sync.WaitGroup{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) Name() (name string) {
|
||||||
|
return CName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) Run(ctx context.Context) (err error) {
|
||||||
|
p.closed = false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) AddHandler(msgType syncproto.MessageType, h Handler) {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
if !p.closed {
|
||||||
|
// unable to add handler after Run
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.handlers[msgType] = append(p.handlers[msgType], h)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) DialAndAddPeer(ctx context.Context, peerId string) (err error) {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
if p.closed {
|
||||||
|
return ErrPoolClosed
|
||||||
|
}
|
||||||
|
if _, ok := p.peersById[peerId]; ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
peer, err := p.dialer.Dial(ctx, peerId)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.peersById[peer.Id()] = &peerEntry{
|
||||||
|
peer: peer,
|
||||||
|
}
|
||||||
|
p.wg.Add(1)
|
||||||
|
go p.readPeerLoop(peer)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) AddAndReadPeer(peer peer.Peer) (err error) {
|
||||||
|
p.mu.Lock()
|
||||||
|
if p.closed {
|
||||||
|
p.mu.Unlock()
|
||||||
|
return ErrPoolClosed
|
||||||
|
}
|
||||||
|
p.peersById[peer.Id()] = &peerEntry{
|
||||||
|
peer: peer,
|
||||||
|
}
|
||||||
|
p.wg.Add(1)
|
||||||
|
p.mu.Unlock()
|
||||||
|
return p.readPeerLoop(peer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) AddPeerIdToGroup(peerId, groupId string) (err error) {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
peer, ok := p.peersById[peerId]
|
||||||
|
if !ok {
|
||||||
|
return ErrPeerNotFound
|
||||||
|
}
|
||||||
|
if slice.FindPos(peer.groupIds, groupId) != -1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
peer.addGroup(groupId)
|
||||||
|
p.peersIdsByGroup[groupId] = append(p.peersIdsByGroup[groupId], peerId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) RemovePeerIdFromGroup(peerId, groupId string) (err error) {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
peer, ok := p.peersById[peerId]
|
||||||
|
if !ok {
|
||||||
|
return ErrPeerNotFound
|
||||||
|
}
|
||||||
|
if slice.FindPos(peer.groupIds, groupId) == -1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
peer.removeGroup(groupId)
|
||||||
|
p.peersIdsByGroup[groupId] = slice.Remove(p.peersIdsByGroup[groupId], peerId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) SendAndWait(ctx context.Context, peerId string, msg *syncproto.Message) (err error) {
|
||||||
|
p.mu.RLock()
|
||||||
|
peer := p.peersById[peerId]
|
||||||
|
p.mu.RUnlock()
|
||||||
|
if peer == nil {
|
||||||
|
return ErrPeerNotFound
|
||||||
|
}
|
||||||
|
repId := p.waiters.NewReplyId()
|
||||||
|
msg.GetHeader().RequestId = repId
|
||||||
|
ch := make(chan Reply, 1)
|
||||||
|
log.With(zap.Uint64("reply id", repId)).Debug("adding waiter for reply id")
|
||||||
|
p.waiters.Add(repId, &waiter{ch: ch})
|
||||||
|
defer p.waiters.Remove(repId)
|
||||||
|
if err = peer.peer.Send(msg); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case rep := <-ch:
|
||||||
|
if rep.Error != nil {
|
||||||
|
return rep.Error
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
case <-ctx.Done():
|
||||||
|
log.Debug("context error happened in send and wait")
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) Broadcast(ctx context.Context, groupId string, msg *syncproto.Message) (err error) {
|
||||||
|
|
||||||
|
//TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) readPeerLoop(peer peer.Peer) (err error) {
|
||||||
|
defer p.wg.Done()
|
||||||
|
limiter := make(chan struct{}, maxSimultaneousOperationsPerStream)
|
||||||
|
for i := 0; i < maxSimultaneousOperationsPerStream; i++ {
|
||||||
|
limiter <- struct{}{}
|
||||||
|
}
|
||||||
|
Loop:
|
||||||
|
for {
|
||||||
|
msg, err := peer.Recv()
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("peer receive error", zap.Error(err), zap.String("peerId", peer.Id()))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-limiter:
|
||||||
|
case <-peer.Context().Done():
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
limiter <- struct{}{}
|
||||||
|
}()
|
||||||
|
p.handleMessage(peer, msg)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
if err = p.removePeer(peer.Id()); err != nil {
|
||||||
|
log.Error("remove peer error", zap.String("peerId", peer.Id()))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) removePeer(peerId string) (err error) {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
_, ok := p.peersById[peerId]
|
||||||
|
if !ok {
|
||||||
|
return ErrPeerNotFound
|
||||||
|
}
|
||||||
|
delete(p.peersById, peerId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) handleMessage(peer peer.Peer, msg *syncproto.Message) {
|
||||||
|
log.With(zap.String("peerId", peer.Id()), zap.String("header", msg.GetHeader().String())).
|
||||||
|
Debug("received message from peer")
|
||||||
|
replyId := msg.GetHeader().GetReplyId()
|
||||||
|
if replyId != 0 {
|
||||||
|
if !p.waiters.Send(replyId, Reply{
|
||||||
|
PeerInfo: peer.Info(),
|
||||||
|
Message: &Message{
|
||||||
|
Message: msg,
|
||||||
|
peer: peer,
|
||||||
|
},
|
||||||
|
}) {
|
||||||
|
log.Debug("received reply with unknown (or expired) replyId", zap.Uint64("replyId", replyId), zap.String("header", msg.GetHeader().String()))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
handlers := p.handlers[msg.GetHeader().GetType()]
|
||||||
|
if len(handlers) == 0 {
|
||||||
|
log.With(zap.String("peerId", peer.Id())).Debug("no handlers for such message")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
message := &Message{Message: msg, peer: peer}
|
||||||
|
|
||||||
|
for _, h := range handlers {
|
||||||
|
if err := h(peer.Context(), message); err != nil {
|
||||||
|
log.Error("handle message error", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) Close(ctx context.Context) (err error) {
|
||||||
|
p.mu.Lock()
|
||||||
|
for _, peer := range p.peersById {
|
||||||
|
peer.peer.Close()
|
||||||
|
}
|
||||||
|
wg := p.wg
|
||||||
|
p.mu.Unlock()
|
||||||
|
if wg != nil {
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type waiter struct {
|
||||||
|
sent int
|
||||||
|
ch chan<- Reply
|
||||||
|
}
|
||||||
|
|
||||||
|
type waiters struct {
|
||||||
|
waiters map[uint64]*waiter
|
||||||
|
replySeq uint64
|
||||||
|
mu sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *waiters) Send(replyId uint64, r Reply) (ok bool) {
|
||||||
|
w.mu.Lock()
|
||||||
|
wait := w.waiters[replyId]
|
||||||
|
if wait == nil {
|
||||||
|
w.mu.Unlock()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
wait.sent++
|
||||||
|
var lastMessage = wait.sent == cap(wait.ch)
|
||||||
|
if lastMessage {
|
||||||
|
delete(w.waiters, replyId)
|
||||||
|
}
|
||||||
|
w.mu.Unlock()
|
||||||
|
wait.ch <- r
|
||||||
|
if lastMessage {
|
||||||
|
close(wait.ch)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *waiters) Add(replyId uint64, wait *waiter) {
|
||||||
|
w.mu.Lock()
|
||||||
|
w.waiters[replyId] = wait
|
||||||
|
w.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *waiters) Remove(id uint64) error {
|
||||||
|
w.mu.Lock()
|
||||||
|
defer w.mu.Unlock()
|
||||||
|
if _, ok := w.waiters[id]; ok {
|
||||||
|
delete(w.waiters, id)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("waiter not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *waiters) NewReplyId() uint64 {
|
||||||
|
res := atomic.AddUint64(&w.replySeq, 1)
|
||||||
|
if res == 0 {
|
||||||
|
return w.NewReplyId()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
45
service/net/pool/request.go
Normal file
45
service/net/pool/request.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package pool
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
// 1. message for one peerId with ack
|
||||||
|
// pool.SendAndWait(ctx context,.C
|
||||||
|
// 2. message for many peers without ack (or group)
|
||||||
|
|
||||||
|
type Request struct {
|
||||||
|
groupId string
|
||||||
|
oneOf []string
|
||||||
|
all []string
|
||||||
|
tryDial bool
|
||||||
|
needReply bool
|
||||||
|
pool *pool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Request) GroupId(groupId string) *Request {
|
||||||
|
r.groupId = groupId
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Request) All(peerIds ...string) *Request {
|
||||||
|
r.all = peerIds
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Request) OneOf(peerIds ...string) *Request {
|
||||||
|
r.oneOf = peerIds
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Request) TryDial(is bool) *Request {
|
||||||
|
r.tryDial = is
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Request) NeedReply(is bool) *Request {
|
||||||
|
r.needReply = is
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Request) Exec(ctx context.Context, msg *Message) *Results {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
53
service/net/pool/result.go
Normal file
53
service/net/pool/result.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package pool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Results of request collects replies and errors
|
||||||
|
// Must be closed after usage r.Close()
|
||||||
|
type Results struct {
|
||||||
|
ctx context.Context
|
||||||
|
cancel func()
|
||||||
|
waiterId uint64
|
||||||
|
ch chan Reply
|
||||||
|
pool *pool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate iterates over replies
|
||||||
|
// if callback will return a non-nil error then iteration stops
|
||||||
|
func (r *Results) Iterate(callback func(r Reply) (err error)) (err error) {
|
||||||
|
if r.ctx == nil || r.ch == nil {
|
||||||
|
return fmt.Errorf("results not initialized")
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-r.ctx.Done():
|
||||||
|
return r.ctx.Err()
|
||||||
|
case m, ok := <-r.ch:
|
||||||
|
if ok {
|
||||||
|
if err = callback(m); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close cancels iteration and unregister reply handler in the pool
|
||||||
|
// Required to call to avoid memory leaks
|
||||||
|
func (r *Results) Close() (err error) {
|
||||||
|
r.cancel()
|
||||||
|
return r.pool.waiters.Remove(r.waiterId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reply presents the result of request executing can be error or result message
|
||||||
|
type Reply struct {
|
||||||
|
PeerInfo peer.Info
|
||||||
|
Error error
|
||||||
|
Message *Message
|
||||||
|
}
|
||||||
18
service/net/rpc/encoding.go
Normal file
18
service/net/rpc/encoding.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package rpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gogo/protobuf/proto"
|
||||||
|
"storj.io/drpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Encoding = enc{}
|
||||||
|
|
||||||
|
type enc struct{}
|
||||||
|
|
||||||
|
func (e enc) Marshal(msg drpc.Message) ([]byte, error) {
|
||||||
|
return msg.(proto.Marshaler).Marshal()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e enc) Unmarshal(buf []byte, msg drpc.Message) error {
|
||||||
|
return msg.(proto.Unmarshaler).Unmarshal(buf)
|
||||||
|
}
|
||||||
132
service/net/rpc/server/drpcserver.go
Normal file
132
service/net/rpc/server/drpcserver.go
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/config"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/rpc"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/secure"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"net"
|
||||||
|
"storj.io/drpc"
|
||||||
|
"storj.io/drpc/drpcserver"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const CName = "net/drpcserver"
|
||||||
|
|
||||||
|
var log = logger.NewNamed(CName)
|
||||||
|
|
||||||
|
func New() DRPCServer {
|
||||||
|
return &drpcServer{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DRPCServer interface {
|
||||||
|
app.ComponentRunnable
|
||||||
|
}
|
||||||
|
|
||||||
|
type drpcServer struct {
|
||||||
|
config config.GrpcServer
|
||||||
|
drpcServer *drpcserver.Server
|
||||||
|
transport secure.Service
|
||||||
|
listeners []secure.ContextListener
|
||||||
|
pool pool.Pool
|
||||||
|
cancel func()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *drpcServer) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
s.config = a.MustComponent(config.CName).(*config.Config).GrpcServer
|
||||||
|
s.transport = a.MustComponent(secure.CName).(secure.Service)
|
||||||
|
s.pool = a.MustComponent(pool.CName).(pool.Pool)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *drpcServer) Name() (name string) {
|
||||||
|
return CName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *drpcServer) Run(ctx context.Context) (err error) {
|
||||||
|
s.drpcServer = drpcserver.New(s)
|
||||||
|
ctx, s.cancel = context.WithCancel(ctx)
|
||||||
|
for _, addr := range s.config.ListenAddrs {
|
||||||
|
tcpList, err := net.Listen("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tlsList := s.transport.TLSListener(tcpList)
|
||||||
|
go s.serve(ctx, tlsList)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *drpcServer) serve(ctx context.Context, lis secure.ContextListener) {
|
||||||
|
l := log.With(zap.String("localAddr", lis.Addr().String()))
|
||||||
|
l.Info("drpc listener started")
|
||||||
|
defer func() {
|
||||||
|
l.Debug("drpc listener stopped")
|
||||||
|
}()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
ctx, conn, err := lis.Accept(ctx)
|
||||||
|
if err != nil {
|
||||||
|
if isTemporary(err) {
|
||||||
|
l.Debug("listener temporary accept error", zap.Error(err))
|
||||||
|
t := time.NewTimer(500 * time.Millisecond)
|
||||||
|
select {
|
||||||
|
case <-t.C:
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := err.(secure.HandshakeError); ok {
|
||||||
|
l.Warn("listener handshake error", zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
l.Error("listener accept error", zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go s.serveConn(ctx, conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *drpcServer) serveConn(ctx context.Context, conn net.Conn) {
|
||||||
|
l := log.With(zap.String("remoteAddr", conn.RemoteAddr().String())).With(zap.String("localAddr", conn.LocalAddr().String()))
|
||||||
|
l.Debug("connection opened")
|
||||||
|
if err := s.drpcServer.ServeOne(ctx, conn); err != nil {
|
||||||
|
if err == context.Canceled || strings.Contains(err.Error(), "EOF") {
|
||||||
|
l.Debug("connection closed")
|
||||||
|
} else {
|
||||||
|
l.Warn("serve connection error", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *drpcServer) HandleRPC(stream drpc.Stream, _ string) (err error) {
|
||||||
|
ctx := stream.Context()
|
||||||
|
sc, err := secure.CtxSecureConn(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.With(zap.String("peer", sc.RemotePeer().String())).Debug("stream opened")
|
||||||
|
return s.pool.AddAndReadPeer(rpc.PeerFromStream(sc, stream, true))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *drpcServer) Close(ctx context.Context) (err error) {
|
||||||
|
if s.cancel != nil {
|
||||||
|
s.cancel()
|
||||||
|
}
|
||||||
|
for _, l := range s.listeners {
|
||||||
|
if e := l.Close(); e != nil {
|
||||||
|
log.Warn("close listener error", zap.Error(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
18
service/net/rpc/server/util.go
Normal file
18
service/net/rpc/server/util.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//go:build !windows
|
||||||
|
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// isTemporary checks if an error is temporary.
|
||||||
|
func isTemporary(err error) bool {
|
||||||
|
var nErr net.Error
|
||||||
|
if errors.As(err, &nErr) {
|
||||||
|
return nErr.Temporary()
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
41
service/net/rpc/server/util_windows.go
Normal file
41
service/net/rpc/server/util_windows.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
_WSAEMFILE syscall.Errno = 10024
|
||||||
|
_WSAENETRESET syscall.Errno = 10052
|
||||||
|
_WSAENOBUFS syscall.Errno = 10055
|
||||||
|
)
|
||||||
|
|
||||||
|
// isTemporary checks if an error is temporary.
|
||||||
|
// see related go issue for more detail: https://go-review.googlesource.com/c/go/+/208537/
|
||||||
|
func isTemporary(err error) bool {
|
||||||
|
var nErr net.Error
|
||||||
|
if !errors.As(err, &nErr) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if nErr.Temporary() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var sErr *os.SyscallError
|
||||||
|
if errors.As(err, &sErr) {
|
||||||
|
switch sErr.Err {
|
||||||
|
case _WSAENETRESET,
|
||||||
|
_WSAEMFILE,
|
||||||
|
_WSAENOBUFS:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
55
service/net/rpc/stream.go
Normal file
55
service/net/rpc/stream.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package rpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto"
|
||||||
|
"github.com/libp2p/go-libp2p-core/sec"
|
||||||
|
"storj.io/drpc"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PeerFromStream(sc sec.SecureConn, stream drpc.Stream, incoming bool) peer.Peer {
|
||||||
|
dp := &drpcPeer{
|
||||||
|
sc: sc,
|
||||||
|
Stream: stream,
|
||||||
|
}
|
||||||
|
dp.info.Id = sc.RemotePeer().String()
|
||||||
|
if incoming {
|
||||||
|
dp.info.Dir = peer.DirInbound
|
||||||
|
} else {
|
||||||
|
dp.info.Dir = peer.DirOutbound
|
||||||
|
}
|
||||||
|
return dp
|
||||||
|
}
|
||||||
|
|
||||||
|
type drpcPeer struct {
|
||||||
|
sc sec.SecureConn
|
||||||
|
info peer.Info
|
||||||
|
drpc.Stream
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *drpcPeer) Id() string {
|
||||||
|
return d.info.Id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *drpcPeer) Info() peer.Info {
|
||||||
|
return d.info
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *drpcPeer) Recv() (msg *syncproto.Message, err error) {
|
||||||
|
msg = &syncproto.Message{}
|
||||||
|
if err = d.Stream.MsgRecv(msg, Encoding); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
atomic.StoreInt64(&d.info.LastActiveUnix, time.Now().Unix())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *drpcPeer) Send(msg *syncproto.Message) (err error) {
|
||||||
|
if err = d.Stream.MsgSend(msg, Encoding); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
atomic.StoreInt64(&d.info.LastActiveUnix, time.Now().Unix())
|
||||||
|
return
|
||||||
|
}
|
||||||
28
service/net/secure/context.go
Normal file
28
service/net/secure/context.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package secure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"github.com/libp2p/go-libp2p-core/sec"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrSecureConnNotFoundInContext = errors.New("secure connection not found in context")
|
||||||
|
)
|
||||||
|
|
||||||
|
type contextKey uint
|
||||||
|
|
||||||
|
const (
|
||||||
|
contextKeySecureConn contextKey = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
func CtxSecureConn(ctx context.Context) (sec.SecureConn, error) {
|
||||||
|
if conn, ok := ctx.Value(contextKeySecureConn).(sec.SecureConn); ok {
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
return nil, ErrSecureConnNotFoundInContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func ctxWithSecureConn(ctx context.Context, conn sec.SecureConn) context.Context {
|
||||||
|
return context.WithValue(ctx, contextKeySecureConn, conn)
|
||||||
|
}
|
||||||
50
service/net/secure/listener.go
Normal file
50
service/net/secure/listener.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package secure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/libp2p/go-libp2p-core/crypto"
|
||||||
|
libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ContextListener interface {
|
||||||
|
// Accept works like net.Listener accept but add context
|
||||||
|
Accept(ctx context.Context) (context.Context, net.Conn, error)
|
||||||
|
|
||||||
|
// Close closes the listener.
|
||||||
|
// Any blocked Accept operations will be unblocked and return errors.
|
||||||
|
Close() error
|
||||||
|
|
||||||
|
// Addr returns the listener's network address.
|
||||||
|
Addr() net.Addr
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTLSListener(key crypto.PrivKey, lis net.Listener) ContextListener {
|
||||||
|
tr, _ := libp2ptls.New(key)
|
||||||
|
return &tlsListener{
|
||||||
|
tr: tr,
|
||||||
|
Listener: lis,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type tlsListener struct {
|
||||||
|
net.Listener
|
||||||
|
tr *libp2ptls.Transport
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *tlsListener) Accept(ctx context.Context) (context.Context, net.Conn, error) {
|
||||||
|
conn, err := p.Listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return p.upgradeConn(ctx, conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *tlsListener) upgradeConn(ctx context.Context, conn net.Conn) (context.Context, net.Conn, error) {
|
||||||
|
secure, err := p.tr.SecureInbound(ctx, conn, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, HandshakeError(err)
|
||||||
|
}
|
||||||
|
ctx = ctxWithSecureConn(ctx, secure)
|
||||||
|
return ctx, secure, nil
|
||||||
|
}
|
||||||
90
service/net/secure/service.go
Normal file
90
service/net/secure/service.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package secure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/config"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||||
|
"github.com/libp2p/go-libp2p-core/crypto"
|
||||||
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
"github.com/libp2p/go-libp2p-core/sec"
|
||||||
|
libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HandshakeError error
|
||||||
|
|
||||||
|
const CName = "net/secure"
|
||||||
|
|
||||||
|
var log = logger.NewNamed(CName)
|
||||||
|
|
||||||
|
func New() Service {
|
||||||
|
return &service{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service interface {
|
||||||
|
TLSListener(lis net.Listener) ContextListener
|
||||||
|
TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error)
|
||||||
|
app.Component
|
||||||
|
}
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
key crypto.PrivKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
account := a.MustComponent(config.CName).(*config.Config).Account
|
||||||
|
decoder := signingkey.NewEDPrivKeyDecoder()
|
||||||
|
pkb, err := decoder.DecodeFromStringIntoBytes(account.SigningKey)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if s.key, err = crypto.UnmarshalEd25519PrivateKey(pkb); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pid, err := peer.Decode(account.PeerId)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var testData = []byte("test data")
|
||||||
|
sign, err := s.key.Sign(testData)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pubKey, err := pid.ExtractPublicKey()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ok, err := pubKey.Verify(testData, sign)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("peerId and privateKey mismatched")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("secure service init", zap.String("peerId", account.PeerId))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Name() (name string) {
|
||||||
|
return CName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) TLSListener(lis net.Listener) ContextListener {
|
||||||
|
return newTLSListener(s.key, lis)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error) {
|
||||||
|
tr, err := libp2ptls.New(s.key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tr.SecureOutbound(ctx, conn, "")
|
||||||
|
}
|
||||||
106
service/node/service.go
Normal file
106
service/node/service.go
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/config"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
const CName = "NodesService"
|
||||||
|
|
||||||
|
var log = logger.NewNamed("nodesservice")
|
||||||
|
|
||||||
|
type Node struct {
|
||||||
|
Address string
|
||||||
|
PeerId string
|
||||||
|
SigningKey signingkey.PubKey
|
||||||
|
EncryptionKey encryptionkey.PubKey
|
||||||
|
SigningKeyString string
|
||||||
|
EncryptionKeyString string
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() app.Component {
|
||||||
|
return &service{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service interface {
|
||||||
|
Nodes() []*Node
|
||||||
|
}
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
nodes []*Node
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
cfg := a.MustComponent(config.CName).(*config.Config)
|
||||||
|
signDecoder := signingkey.NewEDPrivKeyDecoder()
|
||||||
|
rsaDecoder := encryptionkey.NewRSAPrivKeyDecoder()
|
||||||
|
|
||||||
|
var filteredNodes []*Node
|
||||||
|
for _, n := range cfg.Nodes {
|
||||||
|
if n.PeerId == cfg.Account.PeerId {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
node, err := nodeFromConfigNode(n, n.PeerId, signDecoder, rsaDecoder)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.With(zap.String("node", node.PeerId)).Debug("adding peer to known nodes")
|
||||||
|
filteredNodes = append(filteredNodes, node)
|
||||||
|
}
|
||||||
|
s.nodes = filteredNodes
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Name() (name string) {
|
||||||
|
return CName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Run(ctx context.Context) (err error) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Close(ctx context.Context) (err error) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Nodes() []*Node {
|
||||||
|
return s.nodes
|
||||||
|
}
|
||||||
|
|
||||||
|
func nodeFromConfigNode(
|
||||||
|
n config.Node,
|
||||||
|
peerId string,
|
||||||
|
privateSigningDecoder keys.Decoder,
|
||||||
|
privateEncryptionDecoder keys.Decoder) (*Node, error) {
|
||||||
|
decodedSigningKey, err := privateSigningDecoder.DecodeFromString(n.SigningKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
decodedEncryptionKey, err := privateEncryptionDecoder.DecodeFromString(n.EncryptionKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
encKeyString, err := privateEncryptionDecoder.EncodeToString(decodedEncryptionKey.(encryptionkey.PrivKey).GetPublic())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
signKeyString, err := privateSigningDecoder.EncodeToString(decodedSigningKey.(signingkey.PrivKey).GetPublic())
|
||||||
|
|
||||||
|
return &Node{
|
||||||
|
Address: n.Address,
|
||||||
|
PeerId: peerId,
|
||||||
|
SigningKey: decodedSigningKey.(signingkey.PrivKey).GetPublic(),
|
||||||
|
EncryptionKey: decodedEncryptionKey.(encryptionkey.PrivKey).GetPublic(),
|
||||||
|
SigningKeyString: signKeyString,
|
||||||
|
EncryptionKeyString: encKeyString,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
188
service/sync/document/service.go
Normal file
188
service/sync/document/service.go
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
package document
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/account"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/node"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/message"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/treecache"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto"
|
||||||
|
"github.com/gogo/protobuf/proto"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
var CName = "DocumentService"
|
||||||
|
|
||||||
|
var log = logger.NewNamed("documentservice")
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
messageService message.Service
|
||||||
|
treeCache treecache.Service
|
||||||
|
account account.Service
|
||||||
|
// to create new documents we need to know all nodes
|
||||||
|
nodes []*node.Node
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service interface {
|
||||||
|
UpdateDocument(ctx context.Context, id, text string) error
|
||||||
|
CreateDocument(ctx context.Context, text string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() app.Component {
|
||||||
|
return &service{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
s.account = a.MustComponent(account.CName).(account.Service)
|
||||||
|
s.messageService = a.MustComponent(message.CName).(message.Service)
|
||||||
|
s.treeCache = a.MustComponent(treecache.CName).(treecache.Service)
|
||||||
|
|
||||||
|
nodesService := a.MustComponent(node.CName).(node.Service)
|
||||||
|
s.nodes = nodesService.Nodes()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Name() (name string) {
|
||||||
|
return CName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Run(ctx context.Context) (err error) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Close(ctx context.Context) (err error) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) UpdateDocument(ctx context.Context, id, text string) (err error) {
|
||||||
|
var (
|
||||||
|
ch *aclpb.RawChange
|
||||||
|
header *treepb.TreeHeader
|
||||||
|
snapshotPath []string
|
||||||
|
heads []string
|
||||||
|
)
|
||||||
|
log.With(zap.String("id", id), zap.String("text", text)).
|
||||||
|
Debug("updating document")
|
||||||
|
|
||||||
|
err = s.treeCache.Do(ctx, id, func(tree acltree.ACLTree) error {
|
||||||
|
ch, err = tree.AddContent(ctx, func(builder acltree.ChangeBuilder) error {
|
||||||
|
builder.AddChangeContent(
|
||||||
|
&testchangepb.PlainTextChangeData{
|
||||||
|
Content: []*testchangepb.PlainTextChangeContent{
|
||||||
|
createAppendTextChangeContent(text),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
id = tree.ID()
|
||||||
|
heads = tree.Heads()
|
||||||
|
header = tree.Header()
|
||||||
|
snapshotPath = tree.SnapshotPath()
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.With(
|
||||||
|
zap.String("id", id),
|
||||||
|
zap.Strings("heads", heads),
|
||||||
|
zap.String("header", header.String())).
|
||||||
|
Debug("document updated in the database")
|
||||||
|
|
||||||
|
return s.messageService.SendToSpace(ctx, "", syncproto.WrapHeadUpdate(&syncproto.SyncHeadUpdate{
|
||||||
|
Heads: heads,
|
||||||
|
Changes: []*aclpb.RawChange{ch},
|
||||||
|
TreeId: id,
|
||||||
|
SnapshotPath: snapshotPath,
|
||||||
|
TreeHeader: header,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) CreateDocument(ctx context.Context, text string) (id string, err error) {
|
||||||
|
acc := s.account.Account()
|
||||||
|
var (
|
||||||
|
ch *aclpb.RawChange
|
||||||
|
header *treepb.TreeHeader
|
||||||
|
snapshotPath []string
|
||||||
|
heads []string
|
||||||
|
)
|
||||||
|
|
||||||
|
err = s.treeCache.Create(ctx, func(builder acltree.ChangeBuilder) error {
|
||||||
|
err := builder.UserAdd(acc.Identity, acc.EncKey.GetPublic(), aclpb.ACLChange_Admin)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// adding all predefined nodes to the document as admins
|
||||||
|
for _, n := range s.nodes {
|
||||||
|
err = builder.UserAdd(n.SigningKeyString, n.EncryptionKey, aclpb.ACLChange_Admin)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.AddChangeContent(createInitialChangeContent(text))
|
||||||
|
return nil
|
||||||
|
}, func(tree acltree.ACLTree) error {
|
||||||
|
id = tree.ID()
|
||||||
|
heads = tree.Heads()
|
||||||
|
header = tree.Header()
|
||||||
|
snapshotPath = tree.SnapshotPath()
|
||||||
|
ch, err = tree.Storage().GetChange(ctx, heads[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.With(
|
||||||
|
zap.String("id", id),
|
||||||
|
zap.Strings("heads", heads),
|
||||||
|
zap.String("header", header.String())).
|
||||||
|
Debug("document created in the database")
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
log.With(zap.String("id", id), zap.String("text", text)).
|
||||||
|
Debug("creating document")
|
||||||
|
|
||||||
|
err = s.messageService.SendToSpace(ctx, "", syncproto.WrapHeadUpdate(&syncproto.SyncHeadUpdate{
|
||||||
|
Heads: heads,
|
||||||
|
Changes: []*aclpb.RawChange{ch},
|
||||||
|
TreeId: id,
|
||||||
|
SnapshotPath: snapshotPath,
|
||||||
|
TreeHeader: header,
|
||||||
|
}))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return id, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func createInitialChangeContent(text string) proto.Marshaler {
|
||||||
|
return &testchangepb.PlainTextChangeData{
|
||||||
|
Content: []*testchangepb.PlainTextChangeContent{
|
||||||
|
createAppendTextChangeContent(text),
|
||||||
|
},
|
||||||
|
Snapshot: &testchangepb.PlainTextChangeSnapshot{Text: text},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createAppendTextChangeContent(text string) *testchangepb.PlainTextChangeContent {
|
||||||
|
return &testchangepb.PlainTextChangeContent{
|
||||||
|
Value: &testchangepb.PlainTextChangeContentValueOfTextAppend{
|
||||||
|
TextAppend: &testchangepb.PlainTextChangeTextAppend{
|
||||||
|
Text: text,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
135
service/sync/message/service.go
Normal file
135
service/sync/message/service.go
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
package message
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/node"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/requesthandler"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto"
|
||||||
|
"github.com/gogo/protobuf/proto"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var log = logger.NewNamed("messageservice")
|
||||||
|
|
||||||
|
const CName = "MessageService"
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
nodes []*node.Node
|
||||||
|
requestHandler requesthandler.RequestHandler
|
||||||
|
pool pool.Pool
|
||||||
|
sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() app.Component {
|
||||||
|
return &service{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service interface {
|
||||||
|
SendMessage(ctx context.Context, peerId string, msg *syncproto.Sync) error
|
||||||
|
SendToSpace(ctx context.Context, spaceId string, msg *syncproto.Sync) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
s.requestHandler = a.MustComponent(requesthandler.CName).(requesthandler.RequestHandler)
|
||||||
|
s.nodes = a.MustComponent(node.CName).(node.Service).Nodes()
|
||||||
|
s.pool = a.MustComponent(pool.CName).(pool.Pool)
|
||||||
|
s.pool.AddHandler(syncproto.MessageType_MessageTypeSync, s.HandleMessage)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Name() (name string) {
|
||||||
|
return CName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Run(ctx context.Context) (err error) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Close(ctx context.Context) (err error) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) HandleMessage(ctx context.Context, msg *pool.Message) (err error) {
|
||||||
|
log.With(
|
||||||
|
zap.String("peerId", msg.Peer().Id())).
|
||||||
|
Debug("handling message from peer")
|
||||||
|
|
||||||
|
err = msg.Ack()
|
||||||
|
if err != nil {
|
||||||
|
log.With(zap.String("peerId", msg.Peer().Id()), zap.Error(err)).
|
||||||
|
Error("could not ack message")
|
||||||
|
} else {
|
||||||
|
log.With(zap.String("peerId", msg.Peer().Id()), zap.Int("type", int(msg.Header.Type))).
|
||||||
|
Debug("ack returned")
|
||||||
|
}
|
||||||
|
syncMsg := &syncproto.Sync{}
|
||||||
|
err = proto.Unmarshal(msg.Data, syncMsg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
timeoutCtx, cancel := context.WithTimeout(ctx, time.Second*30)
|
||||||
|
defer cancel()
|
||||||
|
return s.requestHandler.HandleSyncMessage(timeoutCtx, msg.Peer().Id(), syncMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) SendMessage(ctx context.Context, peerId string, msg *syncproto.Sync) error {
|
||||||
|
log.With(
|
||||||
|
zap.String("peerId", peerId),
|
||||||
|
zap.String("message", msgType(msg))).
|
||||||
|
Debug("sending message to peer")
|
||||||
|
|
||||||
|
err := s.pool.DialAndAddPeer(context.Background(), peerId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
marshalled, err := proto.Marshal(msg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.pool.SendAndWait(ctx, peerId, &syncproto.Message{
|
||||||
|
Header: &syncproto.Header{Type: syncproto.MessageType_MessageTypeSync},
|
||||||
|
Data: marshalled,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.With(
|
||||||
|
zap.String("peerId", peerId),
|
||||||
|
zap.String("message", msgType(msg)),
|
||||||
|
zap.Error(err)).
|
||||||
|
Debug("failed to send message to peer")
|
||||||
|
} else {
|
||||||
|
log.With(
|
||||||
|
zap.String("peerId", peerId),
|
||||||
|
zap.String("message", msgType(msg))).
|
||||||
|
Debug("message send to peer completed")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) SendToSpace(ctx context.Context, spaceId string, msg *syncproto.Sync) error {
|
||||||
|
for _, rp := range s.nodes {
|
||||||
|
s.SendMessage(ctx, rp.PeerId, msg)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func msgType(content *syncproto.Sync) string {
|
||||||
|
msg := content.GetMessage()
|
||||||
|
switch {
|
||||||
|
case msg.GetFullSyncRequest() != nil:
|
||||||
|
return "FullSyncRequest"
|
||||||
|
case msg.GetFullSyncResponse() != nil:
|
||||||
|
return "FullSyncResponse"
|
||||||
|
case msg.GetHeadUpdate() != nil:
|
||||||
|
return "HeadUpdate"
|
||||||
|
}
|
||||||
|
return "UnknownMessage"
|
||||||
|
}
|
||||||
265
service/sync/requesthandler/requesthandler.go
Normal file
265
service/sync/requesthandler/requesthandler.go
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
package requesthandler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/account"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/treecache"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type requestHandler struct {
|
||||||
|
treeCache treecache.Service
|
||||||
|
account account.Service
|
||||||
|
messageService MessageSender
|
||||||
|
}
|
||||||
|
|
||||||
|
var log = logger.NewNamed("requesthandler")
|
||||||
|
|
||||||
|
func New() app.Component {
|
||||||
|
return &requestHandler{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequestHandler interface {
|
||||||
|
HandleSyncMessage(ctx context.Context, senderId string, request *syncproto.Sync) (err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MessageSender interface {
|
||||||
|
SendMessage(ctx context.Context, peerId string, msg *syncproto.Sync) error
|
||||||
|
SendToSpace(ctx context.Context, spaceId string, msg *syncproto.Sync) error
|
||||||
|
}
|
||||||
|
|
||||||
|
const CName = "SyncRequestHandler"
|
||||||
|
|
||||||
|
func (r *requestHandler) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
r.treeCache = a.MustComponent(treecache.CName).(treecache.Service)
|
||||||
|
r.account = a.MustComponent(account.CName).(account.Service)
|
||||||
|
r.messageService = a.MustComponent("MessageService").(MessageSender)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestHandler) Name() (name string) {
|
||||||
|
return CName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestHandler) Run(ctx context.Context) (err error) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestHandler) Close(ctx context.Context) (err error) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestHandler) HandleSyncMessage(ctx context.Context, senderId string, content *syncproto.Sync) error {
|
||||||
|
msg := content.GetMessage()
|
||||||
|
switch {
|
||||||
|
case msg.GetFullSyncRequest() != nil:
|
||||||
|
return r.HandleFullSyncRequest(ctx, senderId, msg.GetFullSyncRequest())
|
||||||
|
case msg.GetFullSyncResponse() != nil:
|
||||||
|
return r.HandleFullSyncResponse(ctx, senderId, msg.GetFullSyncResponse())
|
||||||
|
case msg.GetHeadUpdate() != nil:
|
||||||
|
return r.HandleHeadUpdate(ctx, senderId, msg.GetHeadUpdate())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestHandler) HandleHeadUpdate(ctx context.Context, senderId string, update *syncproto.SyncHeadUpdate) (err error) {
|
||||||
|
var (
|
||||||
|
fullRequest *syncproto.SyncFullRequest
|
||||||
|
snapshotPath []string
|
||||||
|
result acltree.AddResult
|
||||||
|
)
|
||||||
|
log.With(zap.String("peerId", senderId), zap.String("treeId", update.TreeId)).
|
||||||
|
Debug("received head update message")
|
||||||
|
|
||||||
|
err = r.treeCache.Do(ctx, update.TreeId, func(tree acltree.ACLTree) error {
|
||||||
|
// TODO: check if we already have those changes
|
||||||
|
result, err = tree.AddRawChanges(ctx, update.Changes...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
shouldFullSync := !slice.UnsortedEquals(update.Heads, tree.Heads())
|
||||||
|
snapshotPath = tree.SnapshotPath()
|
||||||
|
if shouldFullSync {
|
||||||
|
fullRequest, err = r.prepareFullSyncRequest(update.TreeId, update.TreeHeader, update.SnapshotPath, tree)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
// if there are no such tree
|
||||||
|
if err == treestorage.ErrUnknownTreeId {
|
||||||
|
// TODO: maybe we can optimize this by sending the header and stuff right away, so when the tree is created we are able to add it on first request
|
||||||
|
fullRequest = &syncproto.SyncFullRequest{
|
||||||
|
TreeId: update.TreeId,
|
||||||
|
TreeHeader: update.TreeHeader,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if we have incompatible heads, or we haven't seen the tree at all
|
||||||
|
if fullRequest != nil {
|
||||||
|
return r.messageService.SendMessage(ctx, senderId, syncproto.WrapFullRequest(fullRequest))
|
||||||
|
}
|
||||||
|
// if error or nothing has changed
|
||||||
|
if err != nil || len(result.Added) == 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// otherwise sending heads update message
|
||||||
|
newUpdate := &syncproto.SyncHeadUpdate{
|
||||||
|
Heads: result.Heads,
|
||||||
|
Changes: result.Added,
|
||||||
|
SnapshotPath: snapshotPath,
|
||||||
|
TreeId: update.TreeId,
|
||||||
|
TreeHeader: update.TreeHeader,
|
||||||
|
}
|
||||||
|
return r.messageService.SendToSpace(ctx, "", syncproto.WrapHeadUpdate(newUpdate))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestHandler) HandleFullSyncRequest(ctx context.Context, senderId string, request *syncproto.SyncFullRequest) (err error) {
|
||||||
|
var (
|
||||||
|
fullResponse *syncproto.SyncFullResponse
|
||||||
|
snapshotPath []string
|
||||||
|
result acltree.AddResult
|
||||||
|
)
|
||||||
|
log.With(zap.String("peerId", senderId), zap.String("treeId", request.TreeId)).
|
||||||
|
Debug("received full sync request message")
|
||||||
|
|
||||||
|
err = r.treeCache.Do(ctx, request.TreeId, func(tree acltree.ACLTree) error {
|
||||||
|
// TODO: check if we already have those changes
|
||||||
|
// if we have non-empty request
|
||||||
|
if len(request.Heads) != 0 {
|
||||||
|
result, err = tree.AddRawChanges(ctx, request.Changes...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snapshotPath = tree.SnapshotPath()
|
||||||
|
fullResponse, err = r.prepareFullSyncResponse(request.TreeId, request.SnapshotPath, request.Changes, tree)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = r.messageService.SendMessage(ctx, senderId, syncproto.WrapFullResponse(fullResponse))
|
||||||
|
// if error or nothing has changed
|
||||||
|
if err != nil || len(result.Added) == 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise sending heads update message
|
||||||
|
newUpdate := &syncproto.SyncHeadUpdate{
|
||||||
|
Heads: result.Heads,
|
||||||
|
Changes: result.Added,
|
||||||
|
SnapshotPath: snapshotPath,
|
||||||
|
TreeId: request.TreeId,
|
||||||
|
TreeHeader: request.TreeHeader,
|
||||||
|
}
|
||||||
|
return r.messageService.SendToSpace(ctx, "def", syncproto.WrapHeadUpdate(newUpdate))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestHandler) HandleFullSyncResponse(ctx context.Context, senderId string, response *syncproto.SyncFullResponse) (err error) {
|
||||||
|
var (
|
||||||
|
snapshotPath []string
|
||||||
|
result acltree.AddResult
|
||||||
|
)
|
||||||
|
log.With(zap.String("peerId", senderId), zap.String("treeId", response.TreeId)).
|
||||||
|
Debug("received full sync response message")
|
||||||
|
|
||||||
|
err = r.treeCache.Do(ctx, response.TreeId, func(tree acltree.ACLTree) error {
|
||||||
|
// TODO: check if we already have those changes
|
||||||
|
result, err = tree.AddRawChanges(ctx, response.Changes...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
snapshotPath = tree.SnapshotPath()
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
// if error or nothing has changed
|
||||||
|
if (err != nil || len(result.Added) == 0) && err != treestorage.ErrUnknownTreeId {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// if we have a new tree
|
||||||
|
if err == treestorage.ErrUnknownTreeId {
|
||||||
|
err = r.createTree(ctx, response)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// sending heads update message
|
||||||
|
newUpdate := &syncproto.SyncHeadUpdate{
|
||||||
|
Heads: result.Heads,
|
||||||
|
Changes: result.Added,
|
||||||
|
SnapshotPath: snapshotPath,
|
||||||
|
TreeId: response.TreeId,
|
||||||
|
}
|
||||||
|
return r.messageService.SendToSpace(ctx, "", syncproto.WrapHeadUpdate(newUpdate))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestHandler) prepareFullSyncRequest(treeId string, header *treepb.TreeHeader, theirPath []string, tree acltree.ACLTree) (*syncproto.SyncFullRequest, error) {
|
||||||
|
ourChanges, err := tree.ChangesAfterCommonSnapshot(theirPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &syncproto.SyncFullRequest{
|
||||||
|
Heads: tree.Heads(),
|
||||||
|
Changes: ourChanges,
|
||||||
|
TreeId: treeId,
|
||||||
|
SnapshotPath: tree.SnapshotPath(),
|
||||||
|
TreeHeader: header,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestHandler) prepareFullSyncResponse(
|
||||||
|
treeId string,
|
||||||
|
theirPath []string,
|
||||||
|
theirChanges []*aclpb.RawChange,
|
||||||
|
tree acltree.ACLTree) (*syncproto.SyncFullResponse, error) {
|
||||||
|
// TODO: we can probably use the common snapshot calculated on the request step from previous peer
|
||||||
|
ourChanges, err := tree.ChangesAfterCommonSnapshot(theirPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
theirMap := make(map[string]struct{})
|
||||||
|
for _, ch := range theirChanges {
|
||||||
|
theirMap[ch.Id] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// filtering our changes, so we will not send the same changes back
|
||||||
|
var final []*aclpb.RawChange
|
||||||
|
for _, ch := range ourChanges {
|
||||||
|
if _, exists := theirMap[ch.Id]; !exists {
|
||||||
|
final = append(final, ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.With(zap.Int("len(changes)", len(final)), zap.String("id", treeId)).
|
||||||
|
Debug("sending changes for tree")
|
||||||
|
|
||||||
|
return &syncproto.SyncFullResponse{
|
||||||
|
Heads: tree.Heads(),
|
||||||
|
Changes: final,
|
||||||
|
TreeId: treeId,
|
||||||
|
SnapshotPath: tree.SnapshotPath(),
|
||||||
|
TreeHeader: tree.Header(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestHandler) createTree(ctx context.Context, response *syncproto.SyncFullResponse) error {
|
||||||
|
return r.treeCache.Add(
|
||||||
|
ctx,
|
||||||
|
response.TreeId,
|
||||||
|
response.TreeHeader,
|
||||||
|
response.Changes,
|
||||||
|
func(tree acltree.ACLTree) error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
111
service/treecache/service.go
Normal file
111
service/treecache/service.go
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package treecache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/ocache"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/account"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
const CName = "treecache"
|
||||||
|
|
||||||
|
// TODO: add context
|
||||||
|
type ACLTreeFunc = func(tree acltree.ACLTree) error
|
||||||
|
type ChangeBuildFunc = func(builder acltree.ChangeBuilder) error
|
||||||
|
|
||||||
|
var log = logger.NewNamed("treecache")
|
||||||
|
|
||||||
|
type Service interface {
|
||||||
|
Do(ctx context.Context, treeId string, f ACLTreeFunc) error
|
||||||
|
Add(ctx context.Context, treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange, f ACLTreeFunc) error
|
||||||
|
Create(ctx context.Context, build ChangeBuildFunc, f ACLTreeFunc) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
treeProvider treestorage.Provider
|
||||||
|
account account.Service
|
||||||
|
cache ocache.OCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() app.ComponentRunnable {
|
||||||
|
return &service{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Create(ctx context.Context, build ChangeBuildFunc, f ACLTreeFunc) error {
|
||||||
|
acc := s.account.Account()
|
||||||
|
st, err := acltree.CreateNewTreeStorageWithACL(acc, build, s.treeProvider.CreateTreeStorage)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := st.TreeID()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.Do(ctx, id, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Do(ctx context.Context, treeId string, f ACLTreeFunc) error {
|
||||||
|
log.
|
||||||
|
With(zap.String("treeId", treeId)).
|
||||||
|
Debug("requesting tree from cache to perform operation")
|
||||||
|
|
||||||
|
tree, err := s.cache.Get(ctx, treeId)
|
||||||
|
defer s.cache.Release(treeId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
aclTree := tree.(acltree.ACLTree)
|
||||||
|
aclTree.Lock()
|
||||||
|
defer aclTree.Unlock()
|
||||||
|
return f(tree.(acltree.ACLTree))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Add(ctx context.Context, treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange, f ACLTreeFunc) error {
|
||||||
|
log.
|
||||||
|
With(zap.String("treeId", treeId), zap.Int("len(changes)", len(changes))).
|
||||||
|
Debug("adding tree with changes")
|
||||||
|
|
||||||
|
_, err := s.treeProvider.CreateTreeStorage(treeId, header, changes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return s.Do(ctx, treeId, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Init(ctx context.Context, a *app.App) (err error) {
|
||||||
|
s.cache = ocache.New(s.loadTree)
|
||||||
|
s.account = a.MustComponent(account.CName).(account.Service)
|
||||||
|
s.treeProvider = treestorage.NewInMemoryTreeStorageProvider()
|
||||||
|
// TODO: for test we should load some predefined keys
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Name() (name string) {
|
||||||
|
return CName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Run(ctx context.Context) (err error) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Close(ctx context.Context) (err error) {
|
||||||
|
return s.cache.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) loadTree(ctx context.Context, id string) (ocache.Object, error) {
|
||||||
|
tree, err := s.treeProvider.TreeStorage(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// TODO: should probably accept nil listeners
|
||||||
|
aclTree, err := acltree.BuildACLTree(tree, s.account.Account(), acltree.NoOpListener{})
|
||||||
|
return aclTree, err
|
||||||
|
}
|
||||||
19
syncproto/helpers.go
Normal file
19
syncproto/helpers.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package syncproto
|
||||||
|
|
||||||
|
func WrapHeadUpdate(update *SyncHeadUpdate) *Sync {
|
||||||
|
return &Sync{Message: &SyncContentValue{
|
||||||
|
Value: &SyncContentValueValueOfHeadUpdate{HeadUpdate: update},
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WrapFullRequest(request *SyncFullRequest) *Sync {
|
||||||
|
return &Sync{Message: &SyncContentValue{
|
||||||
|
Value: &SyncContentValueValueOfFullSyncRequest{FullSyncRequest: request},
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WrapFullResponse(response *SyncFullResponse) *Sync {
|
||||||
|
return &Sync{Message: &SyncContentValue{
|
||||||
|
Value: &SyncContentValueValueOfFullSyncResponse{FullSyncResponse: response},
|
||||||
|
}}
|
||||||
|
}
|
||||||
102
syncproto/proto/sync.proto
Normal file
102
syncproto/proto/sync.proto
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
package anytype;
|
||||||
|
option go_package = "/syncproto";
|
||||||
|
|
||||||
|
import "pkg/acl/aclchanges/aclpb/protos/aclchanges.proto";
|
||||||
|
import "pkg/acl/treestorage/treepb/protos/tree.proto";
|
||||||
|
|
||||||
|
message Message {
|
||||||
|
Header header = 1;
|
||||||
|
bytes data = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Header {
|
||||||
|
bytes traceId = 1;
|
||||||
|
uint64 requestId = 2;
|
||||||
|
uint64 replyId = 3;
|
||||||
|
MessageType type = 4;
|
||||||
|
string debugInfo = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MessageType {
|
||||||
|
MessageTypeSystem = 0;
|
||||||
|
MessageTypeSubscription = 1;
|
||||||
|
MessageTypeSync = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message System {
|
||||||
|
Handshake handshake = 1;
|
||||||
|
Ping ping = 2;
|
||||||
|
Ack ack = 3;
|
||||||
|
|
||||||
|
message Handshake {
|
||||||
|
string protocolVersion = 1;
|
||||||
|
}
|
||||||
|
message Ping {
|
||||||
|
uint64 unixTime = 1;
|
||||||
|
}
|
||||||
|
message Ack {
|
||||||
|
Error error = 2;
|
||||||
|
}
|
||||||
|
message Error {
|
||||||
|
Code code = 1;
|
||||||
|
string description = 2;
|
||||||
|
|
||||||
|
enum Code {
|
||||||
|
UNKNOWN = 0;
|
||||||
|
UNSUPPORTED_PROTOCOL_VERSION = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message Subscription {
|
||||||
|
SubscribeSpace subscribeSpace = 1;
|
||||||
|
UnsubscribeSpace unsubscribeSpace = 2;
|
||||||
|
|
||||||
|
message SubscribeSpace {
|
||||||
|
string spaceId = 1;
|
||||||
|
}
|
||||||
|
message UnsubscribeSpace {
|
||||||
|
string spaceId = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message Sync {
|
||||||
|
string spaceId = 1;
|
||||||
|
ContentValue message = 2;
|
||||||
|
|
||||||
|
message ContentValue {
|
||||||
|
oneof value {
|
||||||
|
HeadUpdate headUpdate = 1;
|
||||||
|
Full.Request fullSyncRequest = 2;
|
||||||
|
Full.Response fullSyncResponse = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message HeadUpdate {
|
||||||
|
repeated string heads = 1;
|
||||||
|
repeated acl.RawChange changes = 2;
|
||||||
|
string treeId = 3;
|
||||||
|
repeated string snapshotPath = 4;
|
||||||
|
tree.TreeHeader treeHeader = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Full {
|
||||||
|
// here with send the request with all changes we have (we already know sender's snapshot path)
|
||||||
|
message Request {
|
||||||
|
repeated string heads = 1;
|
||||||
|
repeated acl.RawChange changes = 2;
|
||||||
|
string treeId = 3;
|
||||||
|
repeated string snapshotPath = 4;
|
||||||
|
tree.TreeHeader treeHeader = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Response {
|
||||||
|
repeated string heads = 1;
|
||||||
|
repeated acl.RawChange changes = 2;
|
||||||
|
string treeId = 3;
|
||||||
|
repeated string snapshotPath = 4;
|
||||||
|
tree.TreeHeader treeHeader = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4345
syncproto/sync.pb.go
Normal file
4345
syncproto/sync.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -107,6 +107,14 @@ func NewEncryptionRsaPubKeyFromBytes(bytes []byte) (PubKey, error) {
|
|||||||
return &EncryptionRsaPubKey{pubKey: *pk}, nil
|
return &EncryptionRsaPubKey{pubKey: *pk}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewRSAPrivKeyDecoder() keys.Decoder {
|
||||||
|
return keys.NewKeyDecoder(NewEncryptionRsaPrivKeyFromBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRSAPubKeyDecoder() keys.Decoder {
|
||||||
|
return keys.NewKeyDecoder(NewEncryptionRsaPubKeyFromBytes)
|
||||||
|
}
|
||||||
|
|
||||||
func keyEquals(k1, k2 keys.Key) bool {
|
func keyEquals(k1, k2 keys.Key) bool {
|
||||||
a, err := k1.Raw()
|
a, err := k1.Raw()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -27,6 +27,10 @@ func NewSigningEd25519PubKeyFromBytes(bytes []byte) (PubKey, error) {
|
|||||||
return UnmarshalEd25519PublicKey(bytes)
|
return UnmarshalEd25519PublicKey(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSigningEd25519PrivKeyFromBytes(bytes []byte) (PrivKey, error) {
|
||||||
|
return UnmarshalEd25519PrivateKey(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
func GenerateRandomEd25519KeyPair() (PrivKey, PubKey, error) {
|
func GenerateRandomEd25519KeyPair() (PrivKey, PubKey, error) {
|
||||||
return GenerateEd25519Key(rand.Reader)
|
return GenerateEd25519Key(rand.Reader)
|
||||||
}
|
}
|
||||||
@ -144,9 +148,10 @@ func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove this one in favor of new one
|
||||||
type Ed25519SigningPubKeyDecoder struct{}
|
type Ed25519SigningPubKeyDecoder struct{}
|
||||||
|
|
||||||
func NewEd25519Decoder() PubKeyDecoder {
|
func NewEd25519PubKeyDecoder() PubKeyDecoder {
|
||||||
return &Ed25519SigningPubKeyDecoder{}
|
return &Ed25519SigningPubKeyDecoder{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,3 +179,11 @@ func (e *Ed25519SigningPubKeyDecoder) EncodeToString(pubkey PubKey) (string, err
|
|||||||
}
|
}
|
||||||
return strkey.Encode(0x5b, raw)
|
return strkey.Encode(0x5b, raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewEDPrivKeyDecoder() keys.Decoder {
|
||||||
|
return keys.NewKeyDecoder(NewSigningEd25519PrivKeyFromBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEDPubKeyDecoder() keys.Decoder {
|
||||||
|
return keys.NewKeyDecoder(NewSigningEd25519PubKeyFromBytes)
|
||||||
|
}
|
||||||
|
|||||||
38
util/keys/decoder.go
Normal file
38
util/keys/decoder.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package keys
|
||||||
|
|
||||||
|
import "github.com/anytypeio/go-anytype-infrastructure-experiments/util/strkey"
|
||||||
|
|
||||||
|
type keyDecoder[T Key] struct {
|
||||||
|
create func([]byte) (T, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKeyDecoder[T Key](create func(bytes []byte) (T, error)) Decoder {
|
||||||
|
return &keyDecoder[T]{
|
||||||
|
create: create,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *keyDecoder[T]) DecodeFromBytes(bytes []byte) (Key, error) {
|
||||||
|
return e.create(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *keyDecoder[T]) DecodeFromString(identity string) (Key, error) {
|
||||||
|
pubKeyRaw, err := strkey.Decode(0x5b, identity)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.DecodeFromBytes(pubKeyRaw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *keyDecoder[T]) DecodeFromStringIntoBytes(identity string) ([]byte, error) {
|
||||||
|
return strkey.Decode(0x5b, identity)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *keyDecoder[T]) EncodeToString(key Key) (string, error) {
|
||||||
|
raw, err := key.Raw()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strkey.Encode(0x5b, raw)
|
||||||
|
}
|
||||||
@ -8,6 +8,13 @@ type Key interface {
|
|||||||
Raw() ([]byte, error)
|
Raw() ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Decoder interface {
|
||||||
|
DecodeFromBytes(bytes []byte) (Key, error)
|
||||||
|
DecodeFromString(identity string) (Key, error)
|
||||||
|
DecodeFromStringIntoBytes(identity string) ([]byte, error)
|
||||||
|
EncodeToString(key Key) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
func KeyEquals(k1, k2 Key) bool {
|
func KeyEquals(k1, k2 Key) bool {
|
||||||
a, err := k1.Raw()
|
a, err := k1.Raw()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
21
util/peer/peer.go
Normal file
21
util/peer/peer.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package peer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||||
|
"github.com/libp2p/go-libp2p-core/crypto"
|
||||||
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
)
|
||||||
|
|
||||||
|
func IDFromSigningPubKey(pubKey signingkey.PubKey) (peer.ID, error) {
|
||||||
|
rawSigning, err := pubKey.Raw()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
libp2pKey, err := crypto.UnmarshalEd25519PublicKey(rawSigning)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return peer.IDFromPublicKey(libp2pKey)
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user