Merge pull request #1 from anytypeio/middleware-compatibility

This commit is contained in:
Mikhail Rakhmanov 2023-01-13 13:09:39 +01:00 committed by GitHub
commit b84dfc595f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 481 additions and 109 deletions

57
.github/workflows/coverage.yml vendored Normal file
View File

@ -0,0 +1,57 @@
on:
pull_request:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
env:
GOPRIVATE: github.com/anytypeio
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '^1.19.5'
- name: git config
run: git config --global url.https://${{ secrets.ANYTYPE_PAT }}@github.com/.insteadOf https://github.com/
# cache {{
- id: go-cache-paths
run: |
echo "GOCACHE=$(go env GOCACHE)" >> $GITHUB_OUTPUT
echo "GOMODCACHE=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
with:
path: |
${{ steps.go-cache-paths.outputs.GOCACHE }}
${{ steps.go-cache-paths.outputs.GOMODCACHE }}
key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-${{ matrix.go-version }}-
# }}
- name: deps
run: make deps
- name: unit tests
run: make test
- name: Quality Gate - Test coverage shall be above threshold
env:
TESTCOVERAGE_THRESHOLD: 0
run: |
go test ./... -coverprofile coverage.out -covermode count
go tool cover -func coverage.out
echo "Quality Gate: checking test coverage is above threshold ..."
echo "Threshold : $TESTCOVERAGE_THRESHOLD %"
totalCoverage=`go tool cover -func=coverage.out | grep total | grep -Eo '[0-9]+\.[0-9]+'`
echo "Current test coverage : $totalCoverage %"
if (( $(echo "$totalCoverage $TESTCOVERAGE_THRESHOLD" | awk '{print ($1 > $2)}') )); then
echo "OK"
else
echo "Current test coverage is below threshold. Please add more unit tests or adjust threshold to a lower value."
echo "Failed"
exit 1
fi

View File

@ -1,20 +1,26 @@
.PHONY: proto test .PHONY: proto test deps
export GOPRIVATE=github.com/anytypeio export GOPRIVATE=github.com/anytypeio
export PATH:=deps:$(PATH)
proto: proto:
@echo 'Generating protobuf packages (Go)...' @echo 'Generating protobuf packages (Go)...'
@$(eval GOGO_START := GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1)
@$(eval P_ACL_RECORDS_PATH_PB := commonspace/object/acl/aclrecordproto) @$(eval P_ACL_RECORDS_PATH_PB := commonspace/object/acl/aclrecordproto)
@$(eval P_TREE_CHANGES_PATH_PB := commonspace/object/tree/treechangeproto) @$(eval P_TREE_CHANGES_PATH_PB := commonspace/object/tree/treechangeproto)
@$(eval P_ACL_RECORDS := M$(P_ACL_RECORDS_PATH_PB)/protos/aclrecord.proto=github.com/anytypeio/any-sync/$(P_ACL_RECORDS_PATH_PB)) @$(eval P_ACL_RECORDS := M$(P_ACL_RECORDS_PATH_PB)/protos/aclrecord.proto=github.com/anytypeio/any-sync/$(P_ACL_RECORDS_PATH_PB))
@$(eval P_TREE_CHANGES := M$(P_TREE_CHANGES_PATH_PB)/protos/treechange.proto=github.com/anytypeio/any-sync/$(P_TREE_CHANGES_PATH_PB)) @$(eval P_TREE_CHANGES := M$(P_TREE_CHANGES_PATH_PB)/protos/treechange.proto=github.com/anytypeio/any-sync/$(P_TREE_CHANGES_PATH_PB))
$(GOGO_START) protoc --gogofaster_out=:. $(P_ACL_RECORDS_PATH_PB)/protos/*.proto protoc --gogofaster_out=:. $(P_ACL_RECORDS_PATH_PB)/protos/*.proto
$(GOGO_START) protoc --gogofaster_out=:. $(P_TREE_CHANGES_PATH_PB)/protos/*.proto protoc --gogofaster_out=:. $(P_TREE_CHANGES_PATH_PB)/protos/*.proto
$(eval PKGMAP := $$(P_TREE_CHANGES),$$(P_ACL_RECORDS)) $(eval PKGMAP := $$(P_TREE_CHANGES),$$(P_ACL_RECORDS))
$(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. --go-drpc_out=protolib=github.com/gogo/protobuf:. commonspace/spacesyncproto/protos/*.proto protoc --gogofaster_out=$(PKGMAP):. --go-drpc_out=protolib=github.com/gogo/protobuf:. commonspace/spacesyncproto/protos/*.proto
$(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. --go-drpc_out=protolib=github.com/gogo/protobuf:. commonfile/fileproto/protos/*.proto protoc --gogofaster_out=$(PKGMAP):. --go-drpc_out=protolib=github.com/gogo/protobuf:. commonfile/fileproto/protos/*.proto
deps:
go mod download
go build -o deps storj.io/drpc/cmd/protoc-gen-go-drpc
go build -o deps github.com/gogo/protobuf/protoc-gen-gogofaster
test: test:
go test ./... --cover go test ./... --cover

View File

@ -6,6 +6,9 @@ func WithPrometheus(reg *prometheus.Registry, namespace, subsystem string) Optio
if subsystem == "" { if subsystem == "" {
subsystem = "cache" subsystem = "cache"
} }
if reg == nil {
return nil
}
return func(cache *oCache) { return func(cache *oCache) {
cache.metrics = &metrics{ cache.metrics = &metrics{
hit: prometheus.NewCounter(prometheus.CounterOpts{ hit: prometheus.NewCounter(prometheus.CounterOpts{

View File

@ -61,7 +61,9 @@ func New(loadFunc LoadFunc, opts ...Option) OCache {
log: log.Sugar(), log: log.Sugar(),
} }
for _, o := range opts { for _, o := range opts {
o(c) if o != nil {
o(c)
}
} }
if c.ttl != 0 && c.gc != 0 { if c.ttl != 0 && c.gc != 0 {
go c.ticker() go c.ticker()

View File

@ -31,10 +31,14 @@ type FileService interface {
GetFile(ctx context.Context, c cid.Cid) (ufsio.ReadSeekCloser, error) GetFile(ctx context.Context, c cid.Cid) (ufsio.ReadSeekCloser, error)
// AddFile adds file to ipfs storage // AddFile adds file to ipfs storage
AddFile(ctx context.Context, r io.Reader) (ipld.Node, error) AddFile(ctx context.Context, r io.Reader) (ipld.Node, error)
// DAGService returns ipld.DAGService object
DAGService() ipld.DAGService
// HasCid checks is CID exists
HasCid(ctx context.Context, c cid.Cid) (exists bool, err error)
app.Component app.Component
} }
type fileService struct { type fileService struct {
bs fileblockstore.BlockStoreLocal
merkledag ipld.DAGService merkledag ipld.DAGService
prefix cid.Prefix prefix cid.Prefix
} }
@ -50,8 +54,8 @@ func (fs *fileService) Init(a *app.App) (err error) {
} }
prefix.MhType = hashFunCode prefix.MhType = hashFunCode
prefix.MhLength = -1 prefix.MhLength = -1
bs := newBlockService(a.MustComponent(fileblockstore.CName).(fileblockstore.BlockStore)) fs.bs = a.MustComponent(fileblockstore.CName).(fileblockstore.BlockStoreLocal)
fs.merkledag = merkledag.NewDAGService(bs) fs.merkledag = merkledag.NewDAGService(newBlockService(fs.bs))
fs.prefix = prefix fs.prefix = prefix
return return
} }
@ -60,6 +64,10 @@ func (fs *fileService) Name() string {
return CName return CName
} }
func (fs *fileService) DAGService() ipld.DAGService {
return fs.merkledag
}
func (fs *fileService) AddFile(ctx context.Context, r io.Reader) (ipld.Node, error) { func (fs *fileService) AddFile(ctx context.Context, r io.Reader) (ipld.Node, error) {
dbp := helpers.DagBuilderParams{ dbp := helpers.DagBuilderParams{
Dagserv: fs.merkledag, Dagserv: fs.merkledag,
@ -86,3 +94,11 @@ func (fs *fileService) GetFile(ctx context.Context, c cid.Cid) (ufsio.ReadSeekCl
} }
return ufsio.NewDagReader(ctx, n, fs.merkledag) return ufsio.NewDagReader(ctx, n, fs.merkledag)
} }
func (fs *fileService) HasCid(ctx context.Context, c cid.Cid) (exists bool, err error) {
res, err := fs.bs.ExistsCids(ctx, []cid.Cid{c})
if err != nil {
return
}
return len(res) > 0, nil
}

View File

@ -1,13 +1,13 @@
package objecttree package objecttree
type DescriptionParser interface { type DescriptionParser interface {
ParseChange(*Change) ([]string, error) ParseChange(ch *Change, isRoot bool) ([]string, error)
} }
var NoOpDescriptionParser = noopDescriptionParser{} var NoOpDescriptionParser = noopDescriptionParser{}
type noopDescriptionParser struct{} type noopDescriptionParser struct{}
func (n noopDescriptionParser) ParseChange(change *Change) ([]string, error) { func (n noopDescriptionParser) ParseChange(ch *Change, isRoot bool) ([]string, error) {
return []string{"DOC"}, nil return []string{"DOC"}, nil
} }

View File

@ -97,18 +97,18 @@ func (mr *MockObjectTreeMockRecorder) Close() *gomock.Call {
} }
// DebugDump mocks base method. // DebugDump mocks base method.
func (m *MockObjectTree) DebugDump() (string, error) { func (m *MockObjectTree) DebugDump(arg0 objecttree.DescriptionParser) (string, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DebugDump") ret := m.ctrl.Call(m, "DebugDump", arg0)
ret0, _ := ret[0].(string) ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error) ret1, _ := ret[1].(error)
return ret0, ret1 return ret0, ret1
} }
// DebugDump indicates an expected call of DebugDump. // DebugDump indicates an expected call of DebugDump.
func (mr *MockObjectTreeMockRecorder) DebugDump() *gomock.Call { func (mr *MockObjectTreeMockRecorder) DebugDump(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper() mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DebugDump", reflect.TypeOf((*MockObjectTree)(nil).DebugDump)) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DebugDump", reflect.TypeOf((*MockObjectTree)(nil).DebugDump), arg0)
} }
// Delete mocks base method. // Delete mocks base method.

View File

@ -52,7 +52,7 @@ type ObjectTree interface {
Heads() []string Heads() []string
Root() *Change Root() *Change
HasChanges(...string) bool HasChanges(...string) bool
DebugDump() (string, error) DebugDump(parser DescriptionParser) (string, error)
IterateRoot(convert ChangeConvertFunc, iterate ChangeIterateFunc) error IterateRoot(convert ChangeConvertFunc, iterate ChangeIterateFunc) error
IterateFrom(id string, convert ChangeConvertFunc, iterate ChangeIterateFunc) error IterateFrom(id string, convert ChangeConvertFunc, iterate ChangeIterateFunc) error
@ -395,7 +395,6 @@ func (ot *objectTree) addRawChanges(ctx context.Context, changesPayload RawChang
} }
return return
} }
return
} }
func (ot *objectTree) createAddResult(oldHeads []string, mode Mode, treeChangesAdded []*Change, rawChanges []*treechangeproto.RawTreeChangeWithId) (addResult AddResult, err error) { func (ot *objectTree) createAddResult(oldHeads []string, mode Mode, treeChangesAdded []*Change, rawChanges []*treechangeproto.RawTreeChangeWithId) (addResult AddResult, err error) {
@ -627,6 +626,6 @@ func (ot *objectTree) validateTree(newChanges []*Change) error {
return ot.validator.ValidateNewChanges(ot.tree, ot.aclList, newChanges) return ot.validator.ValidateNewChanges(ot.tree, ot.aclList, newChanges)
} }
func (ot *objectTree) DebugDump() (string, error) { func (ot *objectTree) DebugDump(parser DescriptionParser) (string, error) {
return ot.tree.Graph(NoOpDescriptionParser) return ot.tree.Graph(parser)
} }

View File

@ -6,6 +6,6 @@ package objecttree
import "fmt" import "fmt"
func (t *Tree) Graph(parser DescriptionParser) (data []string, err error) { func (t *Tree) Graph(parser DescriptionParser) (data string, err error) {
return "", fmt.Errorf("not supported") return "", fmt.Errorf("not supported")
} }

View File

@ -50,7 +50,7 @@ func (t *Tree) Graph(parser DescriptionParser) (data string, err error) {
if ord == "" { if ord == "" {
ord = "miss" ord = "miss"
} }
chSymbs, err := parser.ParseChange(c) chSymbs, err := parser.ParseChange(c, c.Id == t.RootId())
if err != nil { if err != nil {
return err return err
} }

View File

@ -221,18 +221,18 @@ func (mr *MockSyncTreeMockRecorder) Close() *gomock.Call {
} }
// DebugDump mocks base method. // DebugDump mocks base method.
func (m *MockSyncTree) DebugDump() (string, error) { func (m *MockSyncTree) DebugDump(arg0 objecttree.DescriptionParser) (string, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DebugDump") ret := m.ctrl.Call(m, "DebugDump", arg0)
ret0, _ := ret[0].(string) ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error) ret1, _ := ret[1].(error)
return ret0, ret1 return ret0, ret1
} }
// DebugDump indicates an expected call of DebugDump. // DebugDump indicates an expected call of DebugDump.
func (mr *MockSyncTreeMockRecorder) DebugDump() *gomock.Call { func (mr *MockSyncTreeMockRecorder) DebugDump(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper() mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DebugDump", reflect.TypeOf((*MockSyncTree)(nil).DebugDump)) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DebugDump", reflect.TypeOf((*MockSyncTree)(nil).DebugDump), arg0)
} }
// Delete mocks base method. // Delete mocks base method.

View File

@ -55,16 +55,17 @@ var buildObjectTree = objecttree.BuildObjectTree
var createSyncClient = newWrappedSyncClient var createSyncClient = newWrappedSyncClient
type BuildDeps struct { type BuildDeps struct {
SpaceId string SpaceId string
ObjectSync objectsync.ObjectSync ObjectSync objectsync.ObjectSync
Configuration nodeconf.Configuration Configuration nodeconf.Configuration
HeadNotifiable HeadNotifiable HeadNotifiable HeadNotifiable
Listener updatelistener.UpdateListener Listener updatelistener.UpdateListener
AclList list.AclList AclList list.AclList
SpaceStorage spacestorage.SpaceStorage SpaceStorage spacestorage.SpaceStorage
TreeStorage treestorage.TreeStorage TreeStorage treestorage.TreeStorage
TreeUsage *atomic.Int32 TreeUsage *atomic.Int32
SyncStatus syncstatus.StatusUpdater SyncStatus syncstatus.StatusUpdater
WaitTreeRemoteSync bool
} }
func newWrappedSyncClient( func newWrappedSyncClient(
@ -78,9 +79,14 @@ func newWrappedSyncClient(
func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t SyncTree, err error) { func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t SyncTree, err error) {
getTreeRemote := func() (msg *treechangeproto.TreeSyncMessage, err error) { getTreeRemote := func() (msg *treechangeproto.TreeSyncMessage, err error) {
streamChecker := deps.ObjectSync.StreamChecker()
peerId, err := peer.CtxPeerId(ctx) peerId, err := peer.CtxPeerId(ctx)
if err != nil { if err != nil {
return streamChecker.CheckResponsiblePeers()
peerId, err = streamChecker.FirstResponsiblePeer()
if err != nil {
return
}
} }
newTreeRequest := GetRequestFactory().CreateNewTreeRequest() newTreeRequest := GetRequestFactory().CreateNewTreeRequest()
@ -104,6 +110,25 @@ func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t
return return
} }
waitTree := func(wait bool) (msg *treechangeproto.TreeSyncMessage, err error) {
if !wait {
return getTreeRemote()
}
for {
msg, err = getTreeRemote()
if err == nil {
return
}
select {
case <-ctx.Done():
err = fmt.Errorf("waiting for object %s interrupted, context closed", id)
return
default:
break
}
}
}
deps.TreeStorage, err = deps.SpaceStorage.TreeStorage(id) deps.TreeStorage, err = deps.SpaceStorage.TreeStorage(id)
if err == nil { if err == nil {
return buildSyncTree(ctx, false, deps) return buildSyncTree(ctx, false, deps)
@ -122,7 +147,7 @@ func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t
return return
} }
resp, err := getTreeRemote() resp, err := waitTree(deps.WaitTreeRemoteSync)
if err != nil { if err != nil {
return return
} }

View File

@ -16,6 +16,7 @@ import (
type StreamChecker interface { type StreamChecker interface {
CheckResponsiblePeers() CheckResponsiblePeers()
CheckPeerConnection(peerId string) (err error) CheckPeerConnection(peerId string) (err error)
FirstResponsiblePeer() (peerId string, err error)
} }
type streamChecker struct { type streamChecker struct {
@ -28,7 +29,7 @@ type streamChecker struct {
lastCheck *atomic.Time lastCheck *atomic.Time
} }
const streamCheckerInterval = time.Second * 10 const streamCheckerInterval = time.Second * 5
func NewStreamChecker( func NewStreamChecker(
spaceId string, spaceId string,
@ -131,3 +132,15 @@ func (s *streamChecker) createStream(p peer.Peer) (err error) {
} }
return return
} }
func (s *streamChecker) FirstResponsiblePeer() (peerId string, err error) {
nodeIds := s.connector.Configuration().NodeIds(s.spaceId)
for _, nodeId := range nodeIds {
if s.streamPool.HasActiveStream(nodeId) {
peerId = nodeId
return
}
}
err = fmt.Errorf("no responsible peers are connected")
return
}

View File

@ -1,7 +1,7 @@
package commonspace package commonspace
import ( import (
aclrecordproto2 "github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto" aclrecordproto "github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto"
"github.com/anytypeio/any-sync/commonspace/object/keychain" "github.com/anytypeio/any-sync/commonspace/object/keychain"
"github.com/anytypeio/any-sync/commonspace/object/tree/objecttree" "github.com/anytypeio/any-sync/commonspace/object/tree/objecttree"
"github.com/anytypeio/any-sync/commonspace/spacestorage" "github.com/anytypeio/any-sync/commonspace/spacestorage"
@ -75,7 +75,7 @@ func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload sp
} }
// preparing acl // preparing acl
aclRoot := &aclrecordproto2.AclRoot{ aclRoot := &aclrecordproto.AclRoot{
Identity: identity, Identity: identity,
EncryptionKey: encPubKey, EncryptionKey: encPubKey,
SpaceId: spaceId, SpaceId: spaceId,
@ -171,7 +171,7 @@ func storagePayloadForSpaceDerive(payload SpaceDerivePayload) (storagePayload sp
} }
// deriving and encrypting read key // deriving and encrypting read key
readKey, err := aclrecordproto2.AclReadKeyDerive(signPrivKey, encPrivKey) readKey, err := aclrecordproto.AclReadKeyDerive(signPrivKey, encPrivKey)
if err != nil { if err != nil {
return return
} }
@ -181,17 +181,12 @@ func storagePayloadForSpaceDerive(payload SpaceDerivePayload) (storagePayload sp
return return
} }
readKeyHash := hasher.Sum64() readKeyHash := hasher.Sum64()
encReadKey, err := payload.EncryptionKey.GetPublic().Encrypt(readKey.Bytes())
if err != nil {
return
}
// preparing acl // preparing acl
aclRoot := &aclrecordproto2.AclRoot{ aclRoot := &aclrecordproto.AclRoot{
Identity: identity, Identity: identity,
EncryptionKey: encPubKey, EncryptionKey: encPubKey,
SpaceId: spaceId, SpaceId: spaceId,
EncryptedReadKey: encReadKey,
DerivationScheme: SpaceDerivationScheme, DerivationScheme: SpaceDerivationScheme,
CurrentReadKeyHash: readKeyHash, CurrentReadKeyHash: readKeyHash,
} }
@ -221,7 +216,7 @@ func storagePayloadForSpaceDerive(payload SpaceDerivePayload) (storagePayload sp
return return
} }
func marshalAclRoot(aclRoot *aclrecordproto2.AclRoot, key signingkey.PrivKey) (rawWithId *aclrecordproto2.RawAclRecordWithId, err error) { func marshalAclRoot(aclRoot *aclrecordproto.AclRoot, key signingkey.PrivKey) (rawWithId *aclrecordproto.RawAclRecordWithId, err error) {
marshalledRoot, err := aclRoot.Marshal() marshalledRoot, err := aclRoot.Marshal()
if err != nil { if err != nil {
return return
@ -230,7 +225,7 @@ func marshalAclRoot(aclRoot *aclrecordproto2.AclRoot, key signingkey.PrivKey) (r
if err != nil { if err != nil {
return return
} }
raw := &aclrecordproto2.RawAclRecord{ raw := &aclrecordproto.RawAclRecord{
Payload: marshalledRoot, Payload: marshalledRoot,
Signature: signature, Signature: signature,
} }
@ -242,7 +237,7 @@ func marshalAclRoot(aclRoot *aclrecordproto2.AclRoot, key signingkey.PrivKey) (r
if err != nil { if err != nil {
return return
} }
rawWithId = &aclrecordproto2.RawAclRecordWithId{ rawWithId = &aclrecordproto.RawAclRecordWithId{
Payload: marshalledRaw, Payload: marshalledRaw,
Id: aclHeadId, Id: aclHeadId,
} }

View File

@ -133,7 +133,7 @@ func (st *deletionState) CreateDeleteChange(id string, isSnapshot bool) (res []b
} }
change := &spacesyncproto.SettingsData{ change := &spacesyncproto.SettingsData{
Content: []*spacesyncproto.SpaceSettingsContent{ Content: []*spacesyncproto.SpaceSettingsContent{
{content}, {Value: content},
}, },
Snapshot: nil, Snapshot: nil,
} }

View File

@ -55,7 +55,7 @@ func TestProvider_ProcessChange(t *testing.T) {
ch := &objecttree.Change{} ch := &objecttree.Change{}
ch.Model = &spacesyncproto.SettingsData{ ch.Model = &spacesyncproto.SettingsData{
Content: []*spacesyncproto.SpaceSettingsContent{ Content: []*spacesyncproto.SpaceSettingsContent{
{&spacesyncproto.SpaceSettingsContent_ObjectDelete{ {Value: &spacesyncproto.SpaceSettingsContent_ObjectDelete{
ObjectDelete: &spacesyncproto.ObjectDelete{Id: "id1"}, ObjectDelete: &spacesyncproto.ObjectDelete{Id: "id1"},
}}, }},
}, },

View File

@ -84,7 +84,7 @@ type Space interface {
DeriveTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error) DeriveTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error)
CreateTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error) CreateTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error)
PutTree(ctx context.Context, payload treestorage.TreeStorageCreatePayload, listener updatelistener.UpdateListener) (t objecttree.ObjectTree, err error) PutTree(ctx context.Context, payload treestorage.TreeStorageCreatePayload, listener updatelistener.UpdateListener) (t objecttree.ObjectTree, err error)
BuildTree(ctx context.Context, id string, listener updatelistener.UpdateListener) (objecttree.ObjectTree, error) BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (t objecttree.ObjectTree, err error)
DeleteTree(ctx context.Context, id string) (err error) DeleteTree(ctx context.Context, id string) (err error)
SyncStatus() syncstatus.StatusUpdater SyncStatus() syncstatus.StatusUpdater
@ -176,7 +176,10 @@ func (s *space) Init(ctx context.Context) (err error) {
deletionState := deletionstate.NewDeletionState(s.storage) deletionState := deletionstate.NewDeletionState(s.storage)
deps := settings.Deps{ deps := settings.Deps{
BuildFunc: func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error) { BuildFunc: func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error) {
res, err := s.BuildTree(ctx, id, listener) res, err := s.BuildTree(ctx, id, BuildTreeOpts{
Listener: listener,
WaitTreeRemoteSync: false,
})
if err != nil { if err != nil {
return return
} }
@ -281,30 +284,31 @@ func (s *space) PutTree(ctx context.Context, payload treestorage.TreeStorageCrea
TreeUsage: &s.treesUsed, TreeUsage: &s.treesUsed,
SyncStatus: s.syncStatus, SyncStatus: s.syncStatus,
} }
t, err = synctree.PutSyncTree(ctx, payload, deps) return synctree.PutSyncTree(ctx, payload, deps)
// this can happen only for derived trees, when we've synced same tree already
if err == treestorage.ErrTreeExists {
return synctree.BuildSyncTreeOrGetRemote(ctx, payload.RootRawChange.Id, deps)
}
return
} }
func (s *space) BuildTree(ctx context.Context, id string, listener updatelistener.UpdateListener) (t objecttree.ObjectTree, err error) { type BuildTreeOpts struct {
Listener updatelistener.UpdateListener
WaitTreeRemoteSync bool
}
func (s *space) BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (t objecttree.ObjectTree, err error) {
if s.isClosed.Load() { if s.isClosed.Load() {
err = ErrSpaceClosed err = ErrSpaceClosed
return return
} }
deps := synctree.BuildDeps{ deps := synctree.BuildDeps{
SpaceId: s.id, SpaceId: s.id,
ObjectSync: s.objectSync, ObjectSync: s.objectSync,
Configuration: s.configuration, Configuration: s.configuration,
HeadNotifiable: s.headSync, HeadNotifiable: s.headSync,
Listener: listener, Listener: opts.Listener,
AclList: s.aclList, AclList: s.aclList,
SpaceStorage: s.storage, SpaceStorage: s.storage,
TreeUsage: &s.treesUsed, TreeUsage: &s.treesUsed,
SyncStatus: s.syncStatus, SyncStatus: s.syncStatus,
WaitTreeRemoteSync: opts.WaitTreeRemoteSync,
} }
return synctree.BuildSyncTreeOrGetRemote(ctx, id, deps) return synctree.BuildSyncTreeOrGetRemote(ctx, id, deps)
} }

2
deps/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

23
go.mod
View File

@ -3,7 +3,7 @@ module github.com/anytypeio/any-sync
go 1.19 go 1.19
require ( require (
github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 github.com/anytypeio/go-chash v0.0.2
github.com/awalterschulze/gographviz v2.0.3+incompatible github.com/awalterschulze/gographviz v2.0.3+incompatible
github.com/cespare/xxhash v1.1.0 github.com/cespare/xxhash v1.1.0
github.com/cheggaaa/mb/v3 v3.0.0 github.com/cheggaaa/mb/v3 v3.0.0
@ -20,17 +20,17 @@ require (
github.com/ipfs/go-ipld-format v0.4.0 github.com/ipfs/go-ipld-format v0.4.0
github.com/ipfs/go-merkledag v0.8.1 github.com/ipfs/go-merkledag v0.8.1
github.com/ipfs/go-unixfs v0.4.1 github.com/ipfs/go-unixfs v0.4.1
github.com/libp2p/go-libp2p v0.23.2 github.com/libp2p/go-libp2p v0.24.1
github.com/minio/sha256-simd v1.0.0 github.com/minio/sha256-simd v1.0.0
github.com/multiformats/go-multibase v0.1.1 github.com/multiformats/go-multibase v0.1.1
github.com/multiformats/go-multihash v0.2.1 github.com/multiformats/go-multihash v0.2.1
github.com/prometheus/client_golang v1.13.0 github.com/prometheus/client_golang v1.14.0
github.com/stretchr/testify v1.8.1 github.com/stretchr/testify v1.8.1
github.com/zeebo/blake3 v0.2.3 github.com/zeebo/blake3 v0.2.3
github.com/zeebo/errs v1.3.0 github.com/zeebo/errs v1.3.0
go.uber.org/atomic v1.10.0 go.uber.org/atomic v1.10.0
go.uber.org/zap v1.24.0 go.uber.org/zap v1.24.0
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
storj.io/drpc v0.0.32 storj.io/drpc v0.0.32
@ -39,8 +39,9 @@ require (
require ( require (
github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/fogleman/gg v1.3.0 // indirect github.com/fogleman/gg v1.3.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/logr v1.2.3 // indirect
@ -64,24 +65,26 @@ require (
github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect
github.com/ipld/go-codec-dagpb v1.5.0 // indirect github.com/ipld/go-codec-dagpb v1.5.0 // indirect
github.com/ipld/go-ipld-prime v0.19.0 // indirect github.com/ipld/go-ipld-prime v0.19.0 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect github.com/jbenet/goprocess v0.1.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.2 // indirect github.com/klauspost/cpuid/v2 v2.2.2 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-openssl v0.1.0 // indirect github.com/libp2p/go-openssl v0.1.0 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-pointer v0.0.1 // indirect github.com/mattn/go-pointer v0.0.1 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/multiformats/go-multiaddr v0.7.0 // indirect github.com/multiformats/go-multiaddr v0.8.0 // indirect
github.com/multiformats/go-multicodec v0.6.0 // indirect github.com/multiformats/go-multicodec v0.7.0 // indirect
github.com/multiformats/go-multistream v0.3.3 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect github.com/multiformats/go-varint v0.0.7 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // 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/polydawn/refmt v0.89.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
@ -93,7 +96,7 @@ require (
go.uber.org/multierr v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect
golang.org/x/crypto v0.4.0 // indirect golang.org/x/crypto v0.4.0 // indirect
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.3.0 // indirect golang.org/x/sys v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.28.1 // indirect

51
go.sum
View File

@ -42,8 +42,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc= github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc=
github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 h1:kMPPZYmJgbs4AJfodbg2OCXg5cp+9LPAJcLZJqmcghk= github.com/anytypeio/go-chash v0.0.2 h1:BSpyMC3HXNkf2eosQrHM4svov0DrvxL9tb4gnHbdmbA=
github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232/go.mod h1:+PeHBAWp7gUh/yw6uAauKc5ku0w4cFNg6DUddGxoGq0= github.com/anytypeio/go-chash v0.0.2/go.mod h1:G+R6q7jYgNa52NqcRhnNm28pogfWW+cuHtgBktrc2QA=
github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E=
github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs=
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=
@ -56,8 +56,9 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cheggaaa/mb/v3 v3.0.0 h1:+FkV4fAefQfJSsfMtWC9cnSrVYKd3TXcerPTwRuWWfE= github.com/cheggaaa/mb/v3 v3.0.0 h1:+FkV4fAefQfJSsfMtWC9cnSrVYKd3TXcerPTwRuWWfE=
github.com/cheggaaa/mb/v3 v3.0.0/go.mod h1:zCt2QeYukhd/g0bIdNqF+b/kKz1hnLFNDkP49qN5kqI= github.com/cheggaaa/mb/v3 v3.0.0/go.mod h1:zCt2QeYukhd/g0bIdNqF+b/kKz1hnLFNDkP49qN5kqI=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
@ -72,6 +73,8 @@ github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0=
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/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU=
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U=
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc=
@ -258,6 +261,8 @@ github.com/ipld/go-ipld-prime v0.19.0 h1:5axC7rJmPc17Emw6TelxGwnzALk0PdupZ2oj2ro
github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk=
github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk=
github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o=
github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
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=
@ -296,16 +301,17 @@ github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoR
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
github.com/libp2p/go-libp2p v0.23.2 h1:yqyTeKQJyofWXxEv/eEVUvOrGdt/9x+0PIQ4N1kaxmE= github.com/libp2p/go-libp2p v0.24.1 h1:+lS4fqj7RF9egcPq9Yo3iqdRTcDMApzoBbQMhxtwOVw=
github.com/libp2p/go-libp2p v0.23.2/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI= github.com/libp2p/go-libp2p v0.24.1/go.mod h1:5LJqbrqFsUzWrq70JHCYqjATlX4ey8Klpct3OEe8hSI=
github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw=
github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0=
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU=
github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg=
github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4nWRE= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU=
github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo=
github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc=
github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
@ -313,8 +319,9 @@ github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peK
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
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.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
@ -337,16 +344,16 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg
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-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
github.com/multiformats/go-multiaddr v0.7.0 h1:gskHcdaCyPtp9XskVwtvEeQOG465sCohbQIirSyqxrc= github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU=
github.com/multiformats/go-multiaddr v0.7.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs=
github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
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-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI=
github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8=
github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= github.com/multiformats/go-multicodec v0.7.0 h1:rTUjGOwjlhGHbEMbPoSUJowG1spZTVsITRANCjKTUAQ=
github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= github.com/multiformats/go-multicodec v0.7.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw=
github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U=
github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
@ -355,6 +362,7 @@ github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJ
github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108=
github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc=
github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o=
github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg=
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/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
@ -381,13 +389,14 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
@ -489,6 +498,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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-20200602180216-279210d13fed/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.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
@ -503,8 +513,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b h1:SCE/18RnFsLrjydh/R/s5EVvHoZprqEQUuoxK8q2Pc4= golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3 h1:fJwx88sMf5RXwDwziL0/Mn9Wqs+efMSo/RYcL+37W9c=
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
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=
@ -528,7 +538,7 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -582,8 +592,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -616,6 +626,7 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -696,7 +707,7 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -6,8 +6,10 @@ import (
"github.com/anytypeio/any-sync/app" "github.com/anytypeio/any-sync/app"
"github.com/anytypeio/any-sync/app/logger" "github.com/anytypeio/any-sync/app/logger"
"github.com/anytypeio/any-sync/app/ocache" "github.com/anytypeio/any-sync/app/ocache"
"github.com/anytypeio/any-sync/metric"
"github.com/anytypeio/any-sync/net/dialer" "github.com/anytypeio/any-sync/net/dialer"
"github.com/anytypeio/any-sync/net/peer" "github.com/anytypeio/any-sync/net/peer"
"github.com/prometheus/client_golang/prometheus"
"math/rand" "math/rand"
"time" "time"
) )
@ -47,6 +49,10 @@ type pool struct {
func (p *pool) Init(a *app.App) (err error) { func (p *pool) Init(a *app.App) (err error) {
p.dialer = a.MustComponent(dialer.CName).(dialer.Dialer) p.dialer = a.MustComponent(dialer.CName).(dialer.Dialer)
var reg *prometheus.Registry
if m := a.Component(metric.CName); m != nil {
reg = m.(metric.Metric).Registry()
}
p.cache = ocache.New( p.cache = ocache.New(
func(ctx context.Context, id string) (value ocache.Object, err error) { func(ctx context.Context, id string) (value ocache.Object, err error) {
return p.dialer.Dial(ctx, id) return p.dialer.Dial(ctx, id)
@ -54,6 +60,7 @@ func (p *pool) Init(a *app.App) (err error) {
ocache.WithLogger(log.Sugar()), ocache.WithLogger(log.Sugar()),
ocache.WithGCPeriod(time.Minute), ocache.WithGCPeriod(time.Minute),
ocache.WithTTL(time.Minute*5), ocache.WithTTL(time.Minute*5),
ocache.WithPrometheus(reg, "netpool", "cache"),
) )
return nil return nil
} }

View File

@ -5,7 +5,6 @@ import (
commonaccount "github.com/anytypeio/any-sync/accountservice" commonaccount "github.com/anytypeio/any-sync/accountservice"
"github.com/anytypeio/any-sync/app" "github.com/anytypeio/any-sync/app"
"github.com/anytypeio/any-sync/app/logger" "github.com/anytypeio/any-sync/app/logger"
"github.com/anytypeio/any-sync/util/keys"
"github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/sec" "github.com/libp2p/go-libp2p/core/sec"
libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls"
@ -35,16 +34,16 @@ type secureService struct {
} }
func (s *secureService) Init(a *app.App) (err error) { func (s *secureService) Init(a *app.App) (err error) {
account := a.MustComponent("config").(commonaccount.ConfigGetter).GetAccount() account := a.MustComponent(commonaccount.CName).(commonaccount.Service)
pkb, err := keys.DecodeBytesFromString(account.PeerKey) peerKey, err := account.Account().PeerKey.Raw()
if err != nil { if err != nil {
return return
} }
if s.key, err = crypto.UnmarshalEd25519PrivateKey(pkb); err != nil { if s.key, err = crypto.UnmarshalEd25519PrivateKey(peerKey); err != nil {
return return
} }
log.Info("secure service init", zap.String("peerId", account.PeerId)) log.Info("secure service init", zap.String("peerId", account.Account().PeerId))
return nil return nil
} }
@ -62,7 +61,7 @@ func (s *secureService) BasicListener(lis net.Listener, timeoutMillis int) Conte
} }
func (s *secureService) TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error) { func (s *secureService) TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error) {
tr, err := libp2ptls.New(s.key) tr, err := libp2ptls.New(libp2ptls.ID, s.key, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -23,7 +23,7 @@ type ContextListener interface {
} }
func newTLSListener(key crypto.PrivKey, lis net.Listener, timeoutMillis int) ContextListener { func newTLSListener(key crypto.PrivKey, lis net.Listener, timeoutMillis int) ContextListener {
tr, _ := libp2ptls.New(key) tr, _ := libp2ptls.New(libp2ptls.ID, key, nil)
return &tlsListener{ return &tlsListener{
tr: tr, tr: tr,
Listener: lis, Listener: lis,

View File

@ -16,6 +16,8 @@ type Configuration interface {
ConsensusPeers() []string ConsensusPeers() []string
// Addresses returns map[peerId][]addr with connection addresses for all known nodes // Addresses returns map[peerId][]addr with connection addresses for all known nodes
Addresses() map[string][]string Addresses() map[string][]string
// CHash returns nodes consistent table
CHash() chash.CHash
} }
type configuration struct { type configuration struct {
@ -66,3 +68,7 @@ func (c *configuration) Addresses() map[string][]string {
} }
return res return res
} }
func (c *configuration) CHash() chash.CHash {
return c.chash
}

View File

@ -9,6 +9,7 @@ import (
app "github.com/anytypeio/any-sync/app" app "github.com/anytypeio/any-sync/app"
nodeconf "github.com/anytypeio/any-sync/nodeconf" nodeconf "github.com/anytypeio/any-sync/nodeconf"
chash "github.com/anytypeio/go-chash"
gomock "github.com/golang/mock/gomock" gomock "github.com/golang/mock/gomock"
) )
@ -128,6 +129,20 @@ func (mr *MockConfigurationMockRecorder) Addresses() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Addresses", reflect.TypeOf((*MockConfiguration)(nil).Addresses)) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Addresses", reflect.TypeOf((*MockConfiguration)(nil).Addresses))
} }
// CHash mocks base method.
func (m *MockConfiguration) CHash() chash.CHash {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CHash")
ret0, _ := ret[0].(chash.CHash)
return ret0
}
// CHash indicates an expected call of CHash.
func (mr *MockConfigurationMockRecorder) CHash() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CHash", reflect.TypeOf((*MockConfiguration)(nil).CHash))
}
// ConsensusPeers mocks base method. // ConsensusPeers mocks base method.
func (m *MockConfiguration) ConsensusPeers() []string { func (m *MockConfiguration) ConsensusPeers() []string {
m.ctrl.T.Helper() m.ctrl.T.Helper()

View File

@ -4,8 +4,11 @@ import (
accountService "github.com/anytypeio/any-sync/accountservice" accountService "github.com/anytypeio/any-sync/accountservice"
"github.com/anytypeio/any-sync/app" "github.com/anytypeio/any-sync/app"
"github.com/anytypeio/any-sync/commonspace/object/accountdata" "github.com/anytypeio/any-sync/commonspace/object/accountdata"
"github.com/anytypeio/any-sync/nodeconf"
"github.com/anytypeio/any-sync/util/keys"
"github.com/anytypeio/any-sync/util/keys/asymmetric/encryptionkey" "github.com/anytypeio/any-sync/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/any-sync/util/keys/asymmetric/signingkey" "github.com/anytypeio/any-sync/util/keys/asymmetric/signingkey"
"github.com/anytypeio/any-sync/util/peer"
) )
// AccountTestService provides service for test purposes, generates new random account every Init // AccountTestService provides service for test purposes, generates new random account every Init
@ -14,6 +17,9 @@ type AccountTestService struct {
} }
func (s *AccountTestService) Init(a *app.App) (err error) { func (s *AccountTestService) Init(a *app.App) (err error) {
if s.acc != nil {
return
}
encKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048) encKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048)
if err != nil { if err != nil {
return return
@ -27,7 +33,13 @@ func (s *AccountTestService) Init(a *app.App) (err error) {
if err != nil { if err != nil {
return return
} }
peerId, err := peer.IdFromSigningPubKey(signKey.GetPublic())
if err != nil {
return err
}
s.acc = &accountdata.AccountData{ s.acc = &accountdata.AccountData{
PeerId: peerId.String(),
Identity: ident, Identity: ident,
SignKey: signKey, SignKey: signKey,
EncKey: encKey, EncKey: encKey,
@ -42,3 +54,21 @@ func (s *AccountTestService) Name() (name string) {
func (s *AccountTestService) Account() *accountdata.AccountData { func (s *AccountTestService) Account() *accountdata.AccountData {
return s.acc return s.acc
} }
func (s *AccountTestService) NodeConf(addrs []string) nodeconf.NodeConfig {
encSk, err := keys.EncodeKeyToString(s.acc.SignKey)
if err != nil {
panic(err)
}
encEk, err := keys.EncodeKeyToString(s.acc.EncKey)
if err != nil {
panic(err)
}
return nodeconf.NodeConfig{
PeerId: s.acc.PeerId,
Addresses: addrs,
SigningKey: encSk,
EncryptionKey: encEk,
Types: []nodeconf.NodeType{nodeconf.NodeTypeTree},
}
}

View File

@ -8,9 +8,16 @@ import (
"crypto/x509" "crypto/x509"
"errors" "errors"
"github.com/anytypeio/any-sync/util/keys" "github.com/anytypeio/any-sync/util/keys"
"github.com/cespare/xxhash"
mrand "golang.org/x/exp/rand"
"io" "io"
"math"
"math/big"
) )
var bigZero = big.NewInt(0)
var bigOne = big.NewInt(1)
var MinRsaKeyBits = 2048 var MinRsaKeyBits = 2048
var ErrKeyLengthTooSmall = errors.New("error key length too small") var ErrKeyLengthTooSmall = errors.New("error key length too small")
@ -80,6 +87,19 @@ func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) {
return &EncryptionRsaPrivKey{privKey: *priv}, &EncryptionRsaPubKey{pubKey: pk}, nil return &EncryptionRsaPrivKey{privKey: *priv}, &EncryptionRsaPubKey{pubKey: pk}, nil
} }
func DeriveRSAKePair(bits int, seed []byte) (PrivKey, PubKey, error) {
if bits < MinRsaKeyBits {
return nil, nil, ErrKeyLengthTooSmall
}
seed64 := xxhash.Sum64(seed)
priv, err := rsaGenerateMultiPrimeKey(mrand.New(mrand.NewSource(seed64)), 2, bits)
if err != nil {
return nil, nil, err
}
pk := priv.PublicKey
return &EncryptionRsaPrivKey{privKey: *priv}, &EncryptionRsaPubKey{pubKey: pk}, nil
}
func NewEncryptionRsaPrivKeyFromBytes(bytes []byte) (PrivKey, error) { func NewEncryptionRsaPrivKeyFromBytes(bytes []byte) (PrivKey, error) {
sk, err := x509.ParsePKCS1PrivateKey(bytes) sk, err := x509.ParsePKCS1PrivateKey(bytes)
if err != nil { if err != nil {
@ -118,3 +138,138 @@ func keyEquals(k1, k2 keys.Key) bool {
} }
return subtle.ConstantTimeCompare(a, b) == 1 return subtle.ConstantTimeCompare(a, b) == 1
} }
// generateMultiPrimeKey is a copied original rsa.GenerateMultiPrimeKey but without randutil.MaybeReadByte calls
func rsaGenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*rsa.PrivateKey, error) {
priv := new(rsa.PrivateKey)
priv.E = 65537
if nprimes < 2 {
return nil, errors.New("crypto/rsa: GenerateMultiPrimeKey: nprimes must be >= 2")
}
if bits < 64 {
primeLimit := float64(uint64(1) << uint(bits/nprimes))
// pi approximates the number of primes less than primeLimit
pi := primeLimit / (math.Log(primeLimit) - 1)
// Generated primes start with 11 (in binary) so we can only
// use a quarter of them.
pi /= 4
// Use a factor of two to ensure that key generation terminates
// in a reasonable amount of time.
pi /= 2
if pi <= float64(nprimes) {
return nil, errors.New("crypto/rsa: too few primes of given length to generate an RSA key")
}
}
primes := make([]*big.Int, nprimes)
NextSetOfPrimes:
for {
todo := bits
// crypto/rand should set the top two bits in each prime.
// Thus each prime has the form
// p_i = 2^bitlen(p_i) × 0.11... (in base 2).
// And the product is:
// P = 2^todo × α
// where α is the product of nprimes numbers of the form 0.11...
//
// If α < 1/2 (which can happen for nprimes > 2), we need to
// shift todo to compensate for lost bits: the mean value of 0.11...
// is 7/8, so todo + shift - nprimes * log2(7/8) ~= bits - 1/2
// will give good results.
if nprimes >= 7 {
todo += (nprimes - 2) / 5
}
for i := 0; i < nprimes; i++ {
var err error
primes[i], err = randPrime(random, todo/(nprimes-i))
if err != nil {
return nil, err
}
todo -= primes[i].BitLen()
}
// Make sure that primes is pairwise unequal.
for i, prime := range primes {
for j := 0; j < i; j++ {
if prime.Cmp(primes[j]) == 0 {
continue NextSetOfPrimes
}
}
}
n := new(big.Int).Set(bigOne)
totient := new(big.Int).Set(bigOne)
pminus1 := new(big.Int)
for _, prime := range primes {
n.Mul(n, prime)
pminus1.Sub(prime, bigOne)
totient.Mul(totient, pminus1)
}
if n.BitLen() != bits {
// This should never happen for nprimes == 2 because
// crypto/rand should set the top two bits in each prime.
// For nprimes > 2 we hope it does not happen often.
continue NextSetOfPrimes
}
priv.D = new(big.Int)
e := big.NewInt(int64(priv.E))
ok := priv.D.ModInverse(e, totient)
if ok != nil {
priv.Primes = primes
priv.N = n
break
}
}
priv.Precompute()
return priv, nil
}
func randPrime(rand io.Reader, bits int) (*big.Int, error) {
if bits < 2 {
return nil, errors.New("crypto/rand: prime size must be at least 2-bit")
}
b := uint(bits % 8)
if b == 0 {
b = 8
}
bytes := make([]byte, (bits+7)/8)
p := new(big.Int)
for {
if _, err := io.ReadFull(rand, bytes); err != nil {
return nil, err
}
// Clear bits in the first byte to make sure the candidate has a size <= bits.
bytes[0] &= uint8(int(1<<b) - 1)
// Don't let the value be too small, i.e, set the most significant two bits.
// Setting the top two bits, rather than just the top bit,
// means that when two of these values are multiplied together,
// the result isn't ever one bit short.
if b >= 2 {
bytes[0] |= 3 << (b - 2)
} else {
// Here b==1, because b cannot be zero.
bytes[0] |= 1
if len(bytes) > 1 {
bytes[1] |= 0x80
}
}
// Make the value odd since an even number this large certainly isn't prime.
bytes[len(bytes)-1] |= 1
p.SetBytes(bytes)
if p.ProbablyPrime(20) {
return p, nil
}
}
}

View File

@ -0,0 +1,24 @@
package encryptionkey
import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing"
)
func TestDeriveRSAKePair(t *testing.T) {
privKey1, _, err := DeriveRSAKePair(4096, []byte("test seed"))
require.NoError(t, err)
privKey2, _, err := DeriveRSAKePair(4096, []byte("test seed"))
require.NoError(t, err)
data := []byte("test data")
encryped, err := privKey1.GetPublic().Encrypt(data)
require.NoError(t, err)
decrypted, err := privKey2.Decrypt(encryped)
require.NoError(t, err)
assert.Equal(t, data, decrypted)
}