1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-07 21:47:02 +09:00

Merge branch 'stable-any-sync' into GO-2482-full-sync-request-max-size

# Conflicts:
#	commonspace/objectsync/objectsync.go
#	commonspace/spaceutils_test.go
#	go.sum
This commit is contained in:
mcrakhman 2024-06-18 22:12:12 +02:00
commit b3d3b3ea92
No known key found for this signature in database
GPG key ID: DED12CFEF5B8396B
80 changed files with 15552 additions and 1870 deletions

View file

@ -10,7 +10,7 @@ permissions:
contents: write
pull-requests: write
statuses: write
jobs:
cla-check:
uses: anyproto/open/.github/workflows/cla.yml@main

View file

@ -3,75 +3,13 @@ on:
branches:
- main
name: coverage
permissions:
contents: write
pull-requests: write
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
go-version:
- '1.21'
env:
GOPRIVATE: github.com/anyproto
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '${{ matrix.go-version }}'
check-latest: true
- name: git config
run: git config --global url.https://${{ secrets.ANYTYPE_PAT }}@github.com/.insteadOf https://github.com/
- name: Setup license repository
uses: actions/checkout@master
with:
repository: anyproto/open
ref: refs/heads/main
path: ./open
- name: Check licenses
run: |
cd open
python3 tools/generate.py --platform golang
cd ..
sudo gem install license_finder
license_finder inherited_decisions add open/decisions.yml
license_finder --enabled-package-managers gomodules
- 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
generated_pattern='^\/\/ Code generated .* DO NOT EDIT\.$'
files_list=$(grep -rl "$generated_pattern" . | grep '\.go$' | sed 's/^\.\///')
for file in $files_list; do
echo "Removing $file from coverage report"
grep -v "$file" coverage.out > temp_file
mv temp_file coverage.out
done
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
- uses: seriousben/go-patch-cover-action@v1
release-reusable:
uses: anyproto/any-sync-node/.github/workflows/coverage-reusable.yml@main
secrets: inherit # pass all secrets

View file

@ -23,6 +23,7 @@ proto:
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:. net/streampool/testservice/protos/*.proto
protoc --gogofaster_out=:. net/secureservice/handshake/handshakeproto/protos/*.proto
protoc --gogofaster_out=:. net/rpc/limiter/limiterproto/protos/*.proto
protoc --gogofaster_out=$(PKGMAP):. --go-drpc_out=protolib=github.com/gogo/protobuf:. coordinator/coordinatorproto/protos/*.proto
protoc --gogofaster_out=:. --go-drpc_out=protolib=github.com/gogo/protobuf:. consensus/consensusproto/protos/*.proto
protoc --gogofaster_out=:. --go-drpc_out=protolib=github.com/gogo/protobuf:. commonspace/sync/synctestproto/protos/*.proto

198
acl/acl.go Normal file
View file

@ -0,0 +1,198 @@
//go:generate mockgen -destination mock_acl/mock_acl.go github.com/anyproto/any-sync/acl AclService
package acl
import (
"context"
"errors"
"time"
"github.com/prometheus/client_golang/prometheus"
commonaccount "github.com/anyproto/any-sync/accountservice"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/app/ocache"
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/consensus/consensusclient"
"github.com/anyproto/any-sync/consensus/consensusproto"
"github.com/anyproto/any-sync/metric"
"github.com/anyproto/any-sync/util/crypto"
)
const CName = "coordinator.acl"
var log = logger.NewNamed(CName)
var ErrLimitExceed = errors.New("limit exceed")
type Limits struct {
ReadMembers uint32
WriteMembers uint32
}
func New() AclService {
return &aclService{}
}
type AclService interface {
AddRecord(ctx context.Context, spaceId string, rec *consensusproto.RawRecord, limits Limits) (result *consensusproto.RawRecordWithId, err error)
RecordsAfter(ctx context.Context, spaceId, aclHead string) (result []*consensusproto.RawRecordWithId, err error)
Permissions(ctx context.Context, identity crypto.PubKey, spaceId string) (res list.AclPermissions, err error)
OwnerPubKey(ctx context.Context, spaceId string) (ownerIdentity crypto.PubKey, err error)
ReadState(ctx context.Context, spaceId string, f func(s *list.AclState) error) (err error)
HasRecord(ctx context.Context, spaceId, recordId string) (has bool, err error)
app.ComponentRunnable
}
type aclService struct {
consService consensusclient.Service
cache ocache.OCache
accountService commonaccount.Service
}
func (as *aclService) Init(a *app.App) (err error) {
as.consService = app.MustComponent[consensusclient.Service](a)
as.accountService = app.MustComponent[commonaccount.Service](a)
var metricReg *prometheus.Registry
if m := a.Component(metric.CName); m != nil {
metricReg = m.(metric.Metric).Registry()
}
as.cache = ocache.New(as.loadObject,
ocache.WithTTL(5*time.Minute),
ocache.WithLogger(log.Sugar()),
ocache.WithPrometheus(metricReg, "acl", ""),
)
return
}
func (as *aclService) Name() (name string) {
return CName
}
func (as *aclService) loadObject(ctx context.Context, id string) (ocache.Object, error) {
return as.newAclObject(ctx, id)
}
func (as *aclService) get(ctx context.Context, spaceId string) (list.AclList, error) {
obj, err := as.cache.Get(ctx, spaceId)
if err != nil {
return nil, err
}
aObj := obj.(*aclObject)
aObj.lastUsage.Store(time.Now())
return aObj.AclList, nil
}
func (as *aclService) AddRecord(ctx context.Context, spaceId string, rec *consensusproto.RawRecord, limits Limits) (result *consensusproto.RawRecordWithId, err error) {
if limits.ReadMembers <= 1 && limits.WriteMembers <= 1 {
return nil, ErrLimitExceed
}
acl, err := as.get(ctx, spaceId)
if err != nil {
return nil, err
}
acl.RLock()
defer acl.RUnlock()
var beforeReaders, beforeWriters int
for _, acc := range acl.AclState().CurrentAccounts() {
if !acc.Permissions.NoPermissions() {
beforeReaders++
}
if acc.Permissions.CanWrite() {
beforeWriters++
}
}
err = acl.ValidateRawRecord(rec, func(state *list.AclState) error {
var readers, writers int
for _, acc := range state.CurrentAccounts() {
if acc.Permissions.NoPermissions() {
continue
}
readers++
if acc.Permissions.CanWrite() {
writers++
}
}
if readers > beforeReaders && uint32(readers) > limits.ReadMembers {
return ErrLimitExceed
}
if writers > beforeWriters && uint32(writers) > limits.WriteMembers {
return ErrLimitExceed
}
return nil
})
if err != nil {
return
}
return as.consService.AddRecord(ctx, spaceId, rec)
}
func (as *aclService) RecordsAfter(ctx context.Context, spaceId, aclHead string) (result []*consensusproto.RawRecordWithId, err error) {
acl, err := as.get(ctx, spaceId)
if err != nil {
return nil, err
}
acl.RLock()
defer acl.RUnlock()
return acl.RecordsAfter(ctx, aclHead)
}
func (as *aclService) OwnerPubKey(ctx context.Context, spaceId string) (ownerIdentity crypto.PubKey, err error) {
acl, err := as.get(ctx, spaceId)
if err != nil {
return
}
acl.RLock()
defer acl.RUnlock()
return acl.AclState().OwnerPubKey()
}
func (as *aclService) Permissions(ctx context.Context, identity crypto.PubKey, spaceId string) (res list.AclPermissions, err error) {
acl, err := as.get(ctx, spaceId)
if err != nil {
return
}
acl.RLock()
defer acl.RUnlock()
return acl.AclState().Permissions(identity), nil
}
func (as *aclService) ReadState(ctx context.Context, spaceId string, f func(s *list.AclState) error) (err error) {
acl, err := as.get(ctx, spaceId)
if err != nil {
return
}
acl.RLock()
defer acl.RUnlock()
return f(acl.AclState())
}
func (as *aclService) HasRecord(ctx context.Context, spaceId, recordId string) (has bool, err error) {
acl, err := as.get(ctx, spaceId)
if err != nil {
return
}
acl.RLock()
defer acl.RUnlock()
acl.Iterate(func(record *list.AclRecord) (isContinue bool) {
if record.Id == recordId {
has = true
return false
}
return true
})
return
}
func (as *aclService) Run(ctx context.Context) (err error) {
return
}
func (as *aclService) Close(ctx context.Context) (err error) {
return as.cache.Close()
}

237
acl/acl_test.go Normal file
View file

@ -0,0 +1,237 @@
package acl
import (
"context"
"errors"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/commonspace/object/accountdata"
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/consensus/consensusclient"
"github.com/anyproto/any-sync/consensus/consensusclient/mock_consensusclient"
"github.com/anyproto/any-sync/consensus/consensusproto"
"github.com/anyproto/any-sync/testutil/accounttest"
)
var ctx = context.Background()
func TestAclService_AddRecord(t *testing.T) {
ownerKeys, err := accountdata.NewRandom()
require.NoError(t, err)
spaceId := "spaceId"
ownerAcl, err := list.NewTestDerivedAcl(spaceId, ownerKeys)
require.NoError(t, err)
inv, err := ownerAcl.RecordBuilder().BuildInvite()
require.NoError(t, err)
t.Run("success", func(t *testing.T) {
fx := newFixture(t)
defer fx.finish(t)
expRes := list.WrapAclRecord(inv.InviteRec)
var watcherCh = make(chan consensusclient.Watcher)
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
go func() {
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
ownerAcl.Root(),
})
watcherCh <- w
}()
return nil
})
fx.consCl.EXPECT().AddRecord(ctx, spaceId, inv.InviteRec).Return(expRes, nil)
fx.consCl.EXPECT().UnWatch(spaceId)
res, err := fx.AddRecord(ctx, spaceId, inv.InviteRec, Limits{
ReadMembers: 10,
WriteMembers: 10,
})
assert.Equal(t, expRes, res)
assert.NoError(t, err)
w := <-watcherCh
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
expRes,
})
})
t.Run("error", func(t *testing.T) {
fx := newFixture(t)
defer fx.finish(t)
var testErr = errors.New("test")
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
go func() {
w.AddConsensusError(testErr)
}()
return nil
})
fx.consCl.EXPECT().UnWatch(spaceId)
res, err := fx.AddRecord(ctx, spaceId, inv.InviteRec, Limits{
ReadMembers: 10,
WriteMembers: 10,
})
assert.Nil(t, res)
assert.EqualError(t, err, testErr.Error())
})
t.Run("limit exceed", func(t *testing.T) {
fx := newFixture(t)
defer fx.finish(t)
_, err := fx.AddRecord(ctx, spaceId, inv.InviteRec, Limits{
ReadMembers: 1,
WriteMembers: 1,
})
assert.ErrorIs(t, err, ErrLimitExceed)
})
}
func TestAclService_RecordsAfter(t *testing.T) {
ownerKeys, err := accountdata.NewRandom()
require.NoError(t, err)
spaceId := "spaceId"
ownerAcl, err := list.NewTestDerivedAcl(spaceId, ownerKeys)
require.NoError(t, err)
fx := newFixture(t)
defer fx.finish(t)
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
go func() {
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
ownerAcl.Root(),
})
}()
return nil
})
fx.consCl.EXPECT().UnWatch(spaceId)
res, err := fx.RecordsAfter(ctx, spaceId, "")
require.NoError(t, err)
assert.Len(t, res, 1)
}
func TestAclService(t *testing.T) {
ownerKeys, err := accountdata.NewRandom()
require.NoError(t, err)
spaceId := "spaceId"
ownerAcl, err := list.NewTestDerivedAcl(spaceId, ownerKeys)
require.NoError(t, err)
fx := newFixture(t)
defer fx.finish(t)
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
go func() {
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
ownerAcl.Root(),
})
}()
return nil
})
fx.consCl.EXPECT().UnWatch(spaceId)
t.Run("permissions", func(t *testing.T) {
res, err := fx.Permissions(ctx, ownerKeys.SignKey.GetPublic(), spaceId)
require.NoError(t, err)
assert.True(t, res.IsOwner())
})
t.Run("ownerPubKey", func(t *testing.T) {
res, err := fx.OwnerPubKey(ctx, spaceId)
require.NoError(t, err)
assert.Equal(t, ownerKeys.SignKey.GetPublic().Account(), res.Account())
})
}
func TestAclService_ReadState(t *testing.T) {
ownerKeys, err := accountdata.NewRandom()
require.NoError(t, err)
spaceId := "spaceId"
ownerAcl, err := list.NewTestDerivedAcl(spaceId, ownerKeys)
require.NoError(t, err)
fx := newFixture(t)
defer fx.finish(t)
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
go func() {
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
ownerAcl.Root(),
})
}()
return nil
})
fx.consCl.EXPECT().UnWatch(spaceId)
require.NoError(t, fx.ReadState(ctx, spaceId, func(s *list.AclState) error {
assert.NotNil(t, s)
return nil
}))
}
func TestAclService_HasRecord(t *testing.T) {
ownerKeys, err := accountdata.NewRandom()
require.NoError(t, err)
spaceId := "spaceId"
ownerAcl, err := list.NewTestDerivedAcl(spaceId, ownerKeys)
require.NoError(t, err)
fx := newFixture(t)
defer fx.finish(t)
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
go func() {
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
ownerAcl.Root(),
})
}()
return nil
})
fx.consCl.EXPECT().UnWatch(spaceId)
has, err := fx.HasRecord(ctx, spaceId, ownerAcl.Root().Id)
require.NoError(t, err)
assert.True(t, has)
has, err = fx.HasRecord(ctx, spaceId, "non-exists")
require.NoError(t, err)
assert.False(t, has)
}
func newFixture(t *testing.T) *fixture {
ctrl := gomock.NewController(t)
fx := &fixture{
a: new(app.App),
ctrl: ctrl,
consCl: mock_consensusclient.NewMockService(ctrl),
AclService: New(),
}
fx.consCl.EXPECT().Name().Return(consensusclient.CName).AnyTimes()
fx.consCl.EXPECT().Init(gomock.Any()).AnyTimes()
fx.consCl.EXPECT().Run(gomock.Any()).AnyTimes()
fx.consCl.EXPECT().Close(gomock.Any()).AnyTimes()
fx.a.Register(fx.consCl).Register(fx.AclService).Register(&accounttest.AccountTestService{})
require.NoError(t, fx.a.Start(ctx))
return fx
}
type fixture struct {
a *app.App
ctrl *gomock.Controller
consCl *mock_consensusclient.MockService
AclService
}
func (fx *fixture) finish(t *testing.T) {
require.NoError(t, fx.a.Close(ctx))
fx.ctrl.Finish()
}

190
acl/mock_acl/mock_acl.go Normal file
View file

@ -0,0 +1,190 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/anyproto/any-sync/acl (interfaces: AclService)
//
// Generated by this command:
//
// mockgen -destination mock_acl/mock_acl.go github.com/anyproto/any-sync/acl AclService
//
// Package mock_acl is a generated GoMock package.
package mock_acl
import (
context "context"
reflect "reflect"
acl "github.com/anyproto/any-sync/acl"
app "github.com/anyproto/any-sync/app"
list "github.com/anyproto/any-sync/commonspace/object/acl/list"
consensusproto "github.com/anyproto/any-sync/consensus/consensusproto"
crypto "github.com/anyproto/any-sync/util/crypto"
gomock "go.uber.org/mock/gomock"
)
// MockAclService is a mock of AclService interface.
type MockAclService struct {
ctrl *gomock.Controller
recorder *MockAclServiceMockRecorder
}
// MockAclServiceMockRecorder is the mock recorder for MockAclService.
type MockAclServiceMockRecorder struct {
mock *MockAclService
}
// NewMockAclService creates a new mock instance.
func NewMockAclService(ctrl *gomock.Controller) *MockAclService {
mock := &MockAclService{ctrl: ctrl}
mock.recorder = &MockAclServiceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockAclService) EXPECT() *MockAclServiceMockRecorder {
return m.recorder
}
// AddRecord mocks base method.
func (m *MockAclService) AddRecord(arg0 context.Context, arg1 string, arg2 *consensusproto.RawRecord, arg3 acl.Limits) (*consensusproto.RawRecordWithId, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AddRecord", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(*consensusproto.RawRecordWithId)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AddRecord indicates an expected call of AddRecord.
func (mr *MockAclServiceMockRecorder) AddRecord(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRecord", reflect.TypeOf((*MockAclService)(nil).AddRecord), arg0, arg1, arg2, arg3)
}
// Close mocks base method.
func (m *MockAclService) Close(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Close", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Close indicates an expected call of Close.
func (mr *MockAclServiceMockRecorder) Close(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockAclService)(nil).Close), arg0)
}
// HasRecord mocks base method.
func (m *MockAclService) HasRecord(arg0 context.Context, arg1, arg2 string) (bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HasRecord", arg0, arg1, arg2)
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// HasRecord indicates an expected call of HasRecord.
func (mr *MockAclServiceMockRecorder) HasRecord(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasRecord", reflect.TypeOf((*MockAclService)(nil).HasRecord), arg0, arg1, arg2)
}
// Init mocks base method.
func (m *MockAclService) Init(arg0 *app.App) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Init", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Init indicates an expected call of Init.
func (mr *MockAclServiceMockRecorder) Init(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockAclService)(nil).Init), arg0)
}
// Name mocks base method.
func (m *MockAclService) Name() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Name")
ret0, _ := ret[0].(string)
return ret0
}
// Name indicates an expected call of Name.
func (mr *MockAclServiceMockRecorder) Name() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockAclService)(nil).Name))
}
// OwnerPubKey mocks base method.
func (m *MockAclService) OwnerPubKey(arg0 context.Context, arg1 string) (crypto.PubKey, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "OwnerPubKey", arg0, arg1)
ret0, _ := ret[0].(crypto.PubKey)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// OwnerPubKey indicates an expected call of OwnerPubKey.
func (mr *MockAclServiceMockRecorder) OwnerPubKey(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OwnerPubKey", reflect.TypeOf((*MockAclService)(nil).OwnerPubKey), arg0, arg1)
}
// Permissions mocks base method.
func (m *MockAclService) Permissions(arg0 context.Context, arg1 crypto.PubKey, arg2 string) (list.AclPermissions, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Permissions", arg0, arg1, arg2)
ret0, _ := ret[0].(list.AclPermissions)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Permissions indicates an expected call of Permissions.
func (mr *MockAclServiceMockRecorder) Permissions(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Permissions", reflect.TypeOf((*MockAclService)(nil).Permissions), arg0, arg1, arg2)
}
// ReadState mocks base method.
func (m *MockAclService) ReadState(arg0 context.Context, arg1 string, arg2 func(*list.AclState) error) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ReadState", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// ReadState indicates an expected call of ReadState.
func (mr *MockAclServiceMockRecorder) ReadState(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadState", reflect.TypeOf((*MockAclService)(nil).ReadState), arg0, arg1, arg2)
}
// RecordsAfter mocks base method.
func (m *MockAclService) RecordsAfter(arg0 context.Context, arg1, arg2 string) ([]*consensusproto.RawRecordWithId, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RecordsAfter", arg0, arg1, arg2)
ret0, _ := ret[0].([]*consensusproto.RawRecordWithId)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// RecordsAfter indicates an expected call of RecordsAfter.
func (mr *MockAclServiceMockRecorder) RecordsAfter(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordsAfter", reflect.TypeOf((*MockAclService)(nil).RecordsAfter), arg0, arg1, arg2)
}
// Run mocks base method.
func (m *MockAclService) Run(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Run", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Run indicates an expected call of Run.
func (mr *MockAclServiceMockRecorder) Run(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockAclService)(nil).Run), arg0)
}

94
acl/object.go Normal file
View file

@ -0,0 +1,94 @@
package acl
import (
"context"
"slices"
"sync"
"time"
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/commonspace/object/acl/liststorage"
"github.com/anyproto/any-sync/consensus/consensusproto"
"go.uber.org/atomic"
"go.uber.org/zap"
)
func (as *aclService) newAclObject(ctx context.Context, id string) (*aclObject, error) {
obj := &aclObject{
id: id,
aclService: as,
ready: make(chan struct{}),
}
if err := as.consService.Watch(id, obj); err != nil {
return nil, err
}
select {
case <-obj.ready:
if obj.consErr != nil {
_ = as.consService.UnWatch(id)
return nil, obj.consErr
}
return obj, nil
case <-ctx.Done():
_ = as.consService.UnWatch(id)
return nil, ctx.Err()
}
}
type aclObject struct {
id string
aclService *aclService
store liststorage.ListStorage
list.AclList
ready chan struct{}
consErr error
lastUsage atomic.Time
mu sync.Mutex
}
func (a *aclObject) AddConsensusRecords(recs []*consensusproto.RawRecordWithId) {
a.mu.Lock()
defer a.mu.Unlock()
slices.Reverse(recs)
if a.store == nil {
defer close(a.ready)
if a.store, a.consErr = liststorage.NewInMemoryAclListStorage(a.id, recs); a.consErr != nil {
return
}
if a.AclList, a.consErr = list.BuildAclListWithIdentity(a.aclService.accountService.Account(), a.store, list.NoOpAcceptorVerifier{}); a.consErr != nil {
return
}
} else {
a.Lock()
defer a.Unlock()
if err := a.AddRawRecords(recs); err != nil {
log.Warn("unable to add consensus records", zap.Error(err), zap.String("spaceId", a.id))
return
}
}
}
func (a *aclObject) AddConsensusError(err error) {
a.mu.Lock()
defer a.mu.Unlock()
if a.store == nil {
a.consErr = err
close(a.ready)
} else {
log.Warn("got consensus error", zap.Error(err))
}
}
func (a *aclObject) Close() (err error) {
return a.aclService.consService.UnWatch(a.id)
}
func (a *aclObject) TryClose(objectTTL time.Duration) (res bool, err error) {
if a.lastUsage.Load().Before(time.Now().Add(-objectTTL)) {
return true, a.Close()
}
return false, nil
}

View file

@ -4,14 +4,16 @@ import (
"context"
"errors"
"fmt"
"github.com/anyproto/any-sync/app/logger"
"go.uber.org/zap"
"os"
"runtime"
"runtime/debug"
"strings"
"sync"
"time"
"go.uber.org/zap"
"github.com/anyproto/any-sync/app/logger"
)
var (
@ -227,7 +229,7 @@ func (app *App) Start(ctx context.Context) (err error) {
for i := idx; i >= 0; i-- {
if serviceClose, ok := app.components[i].(ComponentRunnable); ok {
if e := serviceClose.Close(ctx); e != nil {
log.Info("close error", zap.String("component", serviceClose.Name()), zap.Error(e))
log.Error("close error", zap.String("component", serviceClose.Name()), zap.Error(e))
}
}
}
@ -235,6 +237,7 @@ func (app *App) Start(ctx context.Context) (err error) {
for i, s := range app.components {
if err = s.Init(app); err != nil {
log.Error("can't init service", zap.String("service", s.Name()), zap.Error(err))
closeServices(i)
return fmt.Errorf("can't init service '%s': %w", s.Name(), err)
}
@ -244,6 +247,7 @@ func (app *App) Start(ctx context.Context) (err error) {
if serviceRun, ok := s.(ComponentRunnable); ok {
start := time.Now()
if err = serviceRun.Run(ctx); err != nil {
log.Error("can't run service", zap.String("service", serviceRun.Name()), zap.Error(err))
closeServices(i)
return fmt.Errorf("can't run service '%s': %w", serviceRun.Name(), err)
}

View file

@ -275,7 +275,6 @@ func (c *oCache) GC() {
var toClose []*entry
for _, e := range c.data {
if e.isActive() && e.lastUsage.Before(deadline) {
e.close = make(chan struct{})
toClose = append(toClose, e)
}
}

File diff suppressed because it is too large Load diff

View file

@ -41,14 +41,17 @@ type DRPCFileClient interface {
DRPCConn() drpc.Conn
BlockGet(ctx context.Context, in *BlockGetRequest) (*BlockGetResponse, error)
BlockPush(ctx context.Context, in *BlockPushRequest) (*BlockPushResponse, error)
BlockPush(ctx context.Context, in *BlockPushRequest) (*Ok, error)
BlocksCheck(ctx context.Context, in *BlocksCheckRequest) (*BlocksCheckResponse, error)
BlocksBind(ctx context.Context, in *BlocksBindRequest) (*BlocksBindResponse, error)
BlocksBind(ctx context.Context, in *BlocksBindRequest) (*Ok, error)
FilesDelete(ctx context.Context, in *FilesDeleteRequest) (*FilesDeleteResponse, error)
FilesInfo(ctx context.Context, in *FilesInfoRequest) (*FilesInfoResponse, error)
FilesGet(ctx context.Context, in *FilesGetRequest) (DRPCFile_FilesGetClient, error)
Check(ctx context.Context, in *CheckRequest) (*CheckResponse, error)
SpaceInfo(ctx context.Context, in *SpaceInfoRequest) (*SpaceInfoResponse, error)
AccountInfo(ctx context.Context, in *AccountInfoRequest) (*AccountInfoResponse, error)
AccountLimitSet(ctx context.Context, in *AccountLimitSetRequest) (*Ok, error)
SpaceLimitSet(ctx context.Context, in *SpaceLimitSetRequest) (*Ok, error)
}
type drpcFileClient struct {
@ -70,8 +73,8 @@ func (c *drpcFileClient) BlockGet(ctx context.Context, in *BlockGetRequest) (*Bl
return out, nil
}
func (c *drpcFileClient) BlockPush(ctx context.Context, in *BlockPushRequest) (*BlockPushResponse, error) {
out := new(BlockPushResponse)
func (c *drpcFileClient) BlockPush(ctx context.Context, in *BlockPushRequest) (*Ok, error) {
out := new(Ok)
err := c.cc.Invoke(ctx, "/filesync.File/BlockPush", drpcEncoding_File_commonfile_fileproto_protos_file_proto{}, in, out)
if err != nil {
return nil, err
@ -88,8 +91,8 @@ func (c *drpcFileClient) BlocksCheck(ctx context.Context, in *BlocksCheckRequest
return out, nil
}
func (c *drpcFileClient) BlocksBind(ctx context.Context, in *BlocksBindRequest) (*BlocksBindResponse, error) {
out := new(BlocksBindResponse)
func (c *drpcFileClient) BlocksBind(ctx context.Context, in *BlocksBindRequest) (*Ok, error) {
out := new(Ok)
err := c.cc.Invoke(ctx, "/filesync.File/BlocksBind", drpcEncoding_File_commonfile_fileproto_protos_file_proto{}, in, out)
if err != nil {
return nil, err
@ -115,6 +118,46 @@ func (c *drpcFileClient) FilesInfo(ctx context.Context, in *FilesInfoRequest) (*
return out, nil
}
func (c *drpcFileClient) FilesGet(ctx context.Context, in *FilesGetRequest) (DRPCFile_FilesGetClient, error) {
stream, err := c.cc.NewStream(ctx, "/filesync.File/FilesGet", drpcEncoding_File_commonfile_fileproto_protos_file_proto{})
if err != nil {
return nil, err
}
x := &drpcFile_FilesGetClient{stream}
if err := x.MsgSend(in, drpcEncoding_File_commonfile_fileproto_protos_file_proto{}); err != nil {
return nil, err
}
if err := x.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type DRPCFile_FilesGetClient interface {
drpc.Stream
Recv() (*FilesGetResponse, error)
}
type drpcFile_FilesGetClient struct {
drpc.Stream
}
func (x *drpcFile_FilesGetClient) GetStream() drpc.Stream {
return x.Stream
}
func (x *drpcFile_FilesGetClient) Recv() (*FilesGetResponse, error) {
m := new(FilesGetResponse)
if err := x.MsgRecv(m, drpcEncoding_File_commonfile_fileproto_protos_file_proto{}); err != nil {
return nil, err
}
return m, nil
}
func (x *drpcFile_FilesGetClient) RecvMsg(m *FilesGetResponse) error {
return x.MsgRecv(m, drpcEncoding_File_commonfile_fileproto_protos_file_proto{})
}
func (c *drpcFileClient) Check(ctx context.Context, in *CheckRequest) (*CheckResponse, error) {
out := new(CheckResponse)
err := c.cc.Invoke(ctx, "/filesync.File/Check", drpcEncoding_File_commonfile_fileproto_protos_file_proto{}, in, out)
@ -142,16 +185,37 @@ func (c *drpcFileClient) AccountInfo(ctx context.Context, in *AccountInfoRequest
return out, nil
}
func (c *drpcFileClient) AccountLimitSet(ctx context.Context, in *AccountLimitSetRequest) (*Ok, error) {
out := new(Ok)
err := c.cc.Invoke(ctx, "/filesync.File/AccountLimitSet", drpcEncoding_File_commonfile_fileproto_protos_file_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcFileClient) SpaceLimitSet(ctx context.Context, in *SpaceLimitSetRequest) (*Ok, error) {
out := new(Ok)
err := c.cc.Invoke(ctx, "/filesync.File/SpaceLimitSet", drpcEncoding_File_commonfile_fileproto_protos_file_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
type DRPCFileServer interface {
BlockGet(context.Context, *BlockGetRequest) (*BlockGetResponse, error)
BlockPush(context.Context, *BlockPushRequest) (*BlockPushResponse, error)
BlockPush(context.Context, *BlockPushRequest) (*Ok, error)
BlocksCheck(context.Context, *BlocksCheckRequest) (*BlocksCheckResponse, error)
BlocksBind(context.Context, *BlocksBindRequest) (*BlocksBindResponse, error)
BlocksBind(context.Context, *BlocksBindRequest) (*Ok, error)
FilesDelete(context.Context, *FilesDeleteRequest) (*FilesDeleteResponse, error)
FilesInfo(context.Context, *FilesInfoRequest) (*FilesInfoResponse, error)
FilesGet(*FilesGetRequest, DRPCFile_FilesGetStream) error
Check(context.Context, *CheckRequest) (*CheckResponse, error)
SpaceInfo(context.Context, *SpaceInfoRequest) (*SpaceInfoResponse, error)
AccountInfo(context.Context, *AccountInfoRequest) (*AccountInfoResponse, error)
AccountLimitSet(context.Context, *AccountLimitSetRequest) (*Ok, error)
SpaceLimitSet(context.Context, *SpaceLimitSetRequest) (*Ok, error)
}
type DRPCFileUnimplementedServer struct{}
@ -160,7 +224,7 @@ func (s *DRPCFileUnimplementedServer) BlockGet(context.Context, *BlockGetRequest
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCFileUnimplementedServer) BlockPush(context.Context, *BlockPushRequest) (*BlockPushResponse, error) {
func (s *DRPCFileUnimplementedServer) BlockPush(context.Context, *BlockPushRequest) (*Ok, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
@ -168,7 +232,7 @@ func (s *DRPCFileUnimplementedServer) BlocksCheck(context.Context, *BlocksCheckR
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCFileUnimplementedServer) BlocksBind(context.Context, *BlocksBindRequest) (*BlocksBindResponse, error) {
func (s *DRPCFileUnimplementedServer) BlocksBind(context.Context, *BlocksBindRequest) (*Ok, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
@ -180,6 +244,10 @@ func (s *DRPCFileUnimplementedServer) FilesInfo(context.Context, *FilesInfoReque
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCFileUnimplementedServer) FilesGet(*FilesGetRequest, DRPCFile_FilesGetStream) error {
return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCFileUnimplementedServer) Check(context.Context, *CheckRequest) (*CheckResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
@ -192,9 +260,17 @@ func (s *DRPCFileUnimplementedServer) AccountInfo(context.Context, *AccountInfoR
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCFileUnimplementedServer) AccountLimitSet(context.Context, *AccountLimitSetRequest) (*Ok, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCFileUnimplementedServer) SpaceLimitSet(context.Context, *SpaceLimitSetRequest) (*Ok, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
type DRPCFileDescription struct{}
func (DRPCFileDescription) NumMethods() int { return 9 }
func (DRPCFileDescription) NumMethods() int { return 12 }
func (DRPCFileDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
switch n {
@ -253,6 +329,15 @@ func (DRPCFileDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver,
)
}, DRPCFileServer.FilesInfo, true
case 6:
return "/filesync.File/FilesGet", drpcEncoding_File_commonfile_fileproto_protos_file_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return nil, srv.(DRPCFileServer).
FilesGet(
in1.(*FilesGetRequest),
&drpcFile_FilesGetStream{in2.(drpc.Stream)},
)
}, DRPCFileServer.FilesGet, true
case 7:
return "/filesync.File/Check", drpcEncoding_File_commonfile_fileproto_protos_file_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCFileServer).
@ -261,7 +346,7 @@ func (DRPCFileDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver,
in1.(*CheckRequest),
)
}, DRPCFileServer.Check, true
case 7:
case 8:
return "/filesync.File/SpaceInfo", drpcEncoding_File_commonfile_fileproto_protos_file_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCFileServer).
@ -270,7 +355,7 @@ func (DRPCFileDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver,
in1.(*SpaceInfoRequest),
)
}, DRPCFileServer.SpaceInfo, true
case 8:
case 9:
return "/filesync.File/AccountInfo", drpcEncoding_File_commonfile_fileproto_protos_file_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCFileServer).
@ -279,6 +364,24 @@ func (DRPCFileDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver,
in1.(*AccountInfoRequest),
)
}, DRPCFileServer.AccountInfo, true
case 10:
return "/filesync.File/AccountLimitSet", drpcEncoding_File_commonfile_fileproto_protos_file_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCFileServer).
AccountLimitSet(
ctx,
in1.(*AccountLimitSetRequest),
)
}, DRPCFileServer.AccountLimitSet, true
case 11:
return "/filesync.File/SpaceLimitSet", drpcEncoding_File_commonfile_fileproto_protos_file_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCFileServer).
SpaceLimitSet(
ctx,
in1.(*SpaceLimitSetRequest),
)
}, DRPCFileServer.SpaceLimitSet, true
default:
return "", nil, nil, nil, false
}
@ -306,14 +409,14 @@ func (x *drpcFile_BlockGetStream) SendAndClose(m *BlockGetResponse) error {
type DRPCFile_BlockPushStream interface {
drpc.Stream
SendAndClose(*BlockPushResponse) error
SendAndClose(*Ok) error
}
type drpcFile_BlockPushStream struct {
drpc.Stream
}
func (x *drpcFile_BlockPushStream) SendAndClose(m *BlockPushResponse) error {
func (x *drpcFile_BlockPushStream) SendAndClose(m *Ok) error {
if err := x.MsgSend(m, drpcEncoding_File_commonfile_fileproto_protos_file_proto{}); err != nil {
return err
}
@ -338,14 +441,14 @@ func (x *drpcFile_BlocksCheckStream) SendAndClose(m *BlocksCheckResponse) error
type DRPCFile_BlocksBindStream interface {
drpc.Stream
SendAndClose(*BlocksBindResponse) error
SendAndClose(*Ok) error
}
type drpcFile_BlocksBindStream struct {
drpc.Stream
}
func (x *drpcFile_BlocksBindStream) SendAndClose(m *BlocksBindResponse) error {
func (x *drpcFile_BlocksBindStream) SendAndClose(m *Ok) error {
if err := x.MsgSend(m, drpcEncoding_File_commonfile_fileproto_protos_file_proto{}); err != nil {
return err
}
@ -384,6 +487,19 @@ func (x *drpcFile_FilesInfoStream) SendAndClose(m *FilesInfoResponse) error {
return x.CloseSend()
}
type DRPCFile_FilesGetStream interface {
drpc.Stream
Send(*FilesGetResponse) error
}
type drpcFile_FilesGetStream struct {
drpc.Stream
}
func (x *drpcFile_FilesGetStream) Send(m *FilesGetResponse) error {
return x.MsgSend(m, drpcEncoding_File_commonfile_fileproto_protos_file_proto{})
}
type DRPCFile_CheckStream interface {
drpc.Stream
SendAndClose(*CheckResponse) error
@ -431,3 +547,35 @@ func (x *drpcFile_AccountInfoStream) SendAndClose(m *AccountInfoResponse) error
}
return x.CloseSend()
}
type DRPCFile_AccountLimitSetStream interface {
drpc.Stream
SendAndClose(*Ok) error
}
type drpcFile_AccountLimitSetStream struct {
drpc.Stream
}
func (x *drpcFile_AccountLimitSetStream) SendAndClose(m *Ok) error {
if err := x.MsgSend(m, drpcEncoding_File_commonfile_fileproto_protos_file_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCFile_SpaceLimitSetStream interface {
drpc.Stream
SendAndClose(*Ok) error
}
type drpcFile_SpaceLimitSetStream struct {
drpc.Stream
}
func (x *drpcFile_SpaceLimitSetStream) SendAndClose(m *Ok) error {
if err := x.MsgSend(m, drpcEncoding_File_commonfile_fileproto_protos_file_proto{}); err != nil {
return err
}
return x.CloseSend()
}

View file

@ -2,6 +2,7 @@ package fileprotoerr
import (
"fmt"
"github.com/anyproto/any-sync/commonfile/fileproto"
"github.com/anyproto/any-sync/net/rpc/rpcerr"
)
@ -11,7 +12,8 @@ var (
ErrUnexpected = errGroup.Register(fmt.Errorf("unexpected fileproto error"), uint64(fileproto.ErrCodes_Unexpected))
ErrCIDNotFound = errGroup.Register(fmt.Errorf("CID not found"), uint64(fileproto.ErrCodes_CIDNotFound))
ErrForbidden = errGroup.Register(fmt.Errorf("forbidden"), uint64(fileproto.ErrCodes_Forbidden))
ErrSpaceLimitExceeded = errGroup.Register(fmt.Errorf("space limit exceeded"), uint64(fileproto.ErrCodes_SpaceLimitExceeded))
ErrSpaceLimitExceeded = errGroup.Register(fmt.Errorf("space limit exceeded"), uint64(fileproto.ErrCodes_LimitExceeded))
ErrQuerySizeExceeded = errGroup.Register(fmt.Errorf("query size exceeded"), uint64(fileproto.ErrCodes_QuerySizeExceeded))
ErrNotEnoughSpace = errGroup.Register(fmt.Errorf("not enough space"), uint64(fileproto.ErrCodes_NotEnoughSpace))
ErrWrongHash = errGroup.Register(fmt.Errorf("wrong block hash"), uint64(fileproto.ErrCodes_WrongHash))
)

View file

@ -7,9 +7,10 @@ enum ErrCodes {
Unexpected = 0;
CIDNotFound = 1;
Forbidden = 2;
SpaceLimitExceeded = 3;
LimitExceeded = 3;
QuerySizeExceeded = 4;
WrongHash = 5;
NotEnoughSpace = 6;
ErrorOffset = 200;
}
@ -17,26 +18,35 @@ service File {
// BlockGet gets one block from a server
rpc BlockGet(BlockGetRequest) returns (BlockGetResponse);
// BlockPush pushes one block to a server
rpc BlockPush(BlockPushRequest) returns (BlockPushResponse);
rpc BlockPush(BlockPushRequest) returns (Ok);
// BlocksCheck checks is CIDs exists
rpc BlocksCheck(BlocksCheckRequest) returns (BlocksCheckResponse);
// BlocksBind binds CIDs to space
rpc BlocksBind(BlocksBindRequest) returns (BlocksBindResponse);
rpc BlocksBind(BlocksBindRequest) returns (Ok);
// FilesDelete deletes files by id
rpc FilesDelete(FilesDeleteRequest) returns (FilesDeleteResponse);
// FilesInfo return info by given files id
rpc FilesInfo(FilesInfoRequest) returns (FilesInfoResponse);
// FilesGet returns a stream that streams all file ids in the space
rpc FilesGet(FilesGetRequest) returns (stream FilesGetResponse);
// Check checks the connection and credentials
rpc Check(CheckRequest) returns (CheckResponse);
// SpaceInfo returns usage, limit, etc about space
rpc SpaceInfo(SpaceInfoRequest) returns (SpaceInfoResponse);
// AccountInfo returns usage, limit, etc by all spaces
rpc AccountInfo(AccountInfoRequest) returns (AccountInfoResponse);
// AccountLimitSet sets the account file storage limit (available only for nodeconf members)
rpc AccountLimitSet(AccountLimitSetRequest) returns (Ok);
// SpaceLimitSet sets the space limit. Limit 0 means space will use account limits.
rpc SpaceLimitSet(SpaceLimitSetRequest) returns (Ok);
}
message Ok {}
message BlockGetRequest {
string spaceId = 1;
bytes cid = 2;
bool wait = 3;
}
message BlockGetResponse {
@ -51,9 +61,6 @@ message BlockPushRequest {
bytes data = 4;
}
message BlockPushResponse {}
message BlocksCheckRequest {
string spaceId = 1;
repeated bytes cids = 2;
@ -80,8 +87,6 @@ message BlocksBindRequest {
repeated bytes cids = 3;
}
message BlocksBindResponse {}
message FilesDeleteRequest {
string spaceId = 1;
@ -105,6 +110,15 @@ message FileInfo {
uint32 cidsCount = 3;
}
message FilesGetRequest {
string spaceId = 1;
}
message FilesGetResponse {
string fileId = 1;
}
message CheckRequest {}
message CheckResponse {
@ -129,8 +143,22 @@ message AccountInfoRequest {
}
message AccountInfoResponse {
// the shared limit excluding isolated spaces
uint64 limitBytes = 1;
uint64 totalUsageBytes = 2;
uint64 totalCidsCount = 3;
repeated SpaceInfoResponse spaces = 4;
// the total limit including isolated spaces
uint64 accountLimitBytes = 5;
}
message AccountLimitSetRequest {
string identity = 1;
uint64 limit = 2;
}
message SpaceLimitSetRequest {
string spaceId = 1;
uint64 limit = 2;
}

View file

@ -1,3 +1,4 @@
//go:generate mockgen -destination mock_aclclient/mock_aclclient.go github.com/anyproto/any-sync/commonspace/acl/aclclient AclJoiningClient,AclSpaceClient
package aclclient
import (
@ -10,7 +11,7 @@ import (
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/commonspace/object/acl/liststorage"
"github.com/anyproto/any-sync/consensus/consensusproto"
"github.com/anyproto/any-sync/coordinator/coordinatorclient"
"github.com/anyproto/any-sync/node/nodeclient"
)
const CName = "common.acl.aclclient"
@ -24,8 +25,8 @@ type AclJoiningClient interface {
}
type aclJoiningClient struct {
coordinatorClient coordinatorclient.CoordinatorClient
keys *accountdata.AccountKeys
nodeClient nodeclient.NodeClient
keys *accountdata.AccountKeys
}
func NewAclJoiningClient() AclJoiningClient {
@ -37,13 +38,13 @@ func (c *aclJoiningClient) Name() (name string) {
}
func (c *aclJoiningClient) Init(a *app.App) (err error) {
c.coordinatorClient = a.MustComponent(coordinatorclient.CName).(coordinatorclient.CoordinatorClient)
c.nodeClient = a.MustComponent(nodeclient.CName).(nodeclient.NodeClient)
c.keys = a.MustComponent(accountservice.CName).(accountservice.Service).Account()
return nil
}
func (c *aclJoiningClient) AclGetRecords(ctx context.Context, spaceId, aclHead string) (recs []*consensusproto.RawRecordWithId, err error) {
return c.coordinatorClient.AclGetRecords(ctx, spaceId, aclHead)
return c.nodeClient.AclGetRecords(ctx, spaceId, aclHead)
}
func (c *aclJoiningClient) getAcl(ctx context.Context, spaceId string) (l list.AclList, err error) {
@ -75,7 +76,7 @@ func (c *aclJoiningClient) CancelJoin(ctx context.Context, spaceId string) (err
if err != nil {
return
}
_, err = c.coordinatorClient.AclAddRecord(ctx, spaceId, res)
_, err = c.nodeClient.AclAddRecord(ctx, spaceId, res)
return
}
@ -98,7 +99,7 @@ func (c *aclJoiningClient) RequestJoin(ctx context.Context, spaceId string, payl
if err != nil {
return
}
recWithId, err := c.coordinatorClient.AclAddRecord(ctx, spaceId, rec)
recWithId, err := c.nodeClient.AclAddRecord(ctx, spaceId, rec)
if err != nil {
return
}
@ -125,6 +126,6 @@ func (c *aclJoiningClient) CancelRemoveSelf(ctx context.Context, spaceId string)
if err != nil {
return
}
_, err = c.coordinatorClient.AclAddRecord(ctx, spaceId, newRec)
_, err = c.nodeClient.AclAddRecord(ctx, spaceId, newRec)
return
}

View file

@ -9,7 +9,7 @@ import (
"github.com/anyproto/any-sync/commonspace/object/acl/syncacl"
"github.com/anyproto/any-sync/commonspace/spacestate"
"github.com/anyproto/any-sync/consensus/consensusproto"
"github.com/anyproto/any-sync/coordinator/coordinatorclient"
"github.com/anyproto/any-sync/node/nodeclient"
"github.com/anyproto/any-sync/util/crypto"
)
@ -45,13 +45,13 @@ func NewAclSpaceClient() AclSpaceClient {
}
type aclSpaceClient struct {
coordinatorClient coordinatorclient.CoordinatorClient
acl list.AclList
spaceId string
nodeClient nodeclient.NodeClient
acl list.AclList
spaceId string
}
func (c *aclSpaceClient) Init(a *app.App) (err error) {
c.coordinatorClient = a.MustComponent(coordinatorclient.CName).(coordinatorclient.CoordinatorClient)
c.nodeClient = a.MustComponent(nodeclient.CName).(nodeclient.NodeClient)
c.acl = a.MustComponent(syncacl.CName).(list.AclList)
c.spaceId = a.MustComponent(spacestate.CName).(*spacestate.SpaceState).SpaceId
return nil
@ -132,6 +132,10 @@ func (c *aclSpaceClient) RevokeAllInvites(ctx context.Context) (err error) {
func (c *aclSpaceClient) StopSharing(ctx context.Context, readKeyChange list.ReadKeyChangePayload) (err error) {
c.acl.Lock()
if c.acl.AclState().IsEmpty() {
c.acl.Unlock()
return
}
var (
identities []crypto.PubKey
recIds []string
@ -217,7 +221,7 @@ func (c *aclSpaceClient) AddRecord(ctx context.Context, consRec *consensusproto.
}
func (c *aclSpaceClient) sendRecordAndUpdate(ctx context.Context, spaceId string, rec *consensusproto.RawRecord) (err error) {
res, err := c.coordinatorClient.AclAddRecord(ctx, spaceId, rec)
res, err := c.nodeClient.AclAddRecord(ctx, spaceId, rec)
if err != nil {
return
}

View file

@ -0,0 +1,131 @@
package aclclient
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/commonspace/object/acl/syncacl"
"github.com/anyproto/any-sync/commonspace/spacestate"
"github.com/anyproto/any-sync/consensus/consensusproto"
"github.com/anyproto/any-sync/node/nodeclient"
"github.com/anyproto/any-sync/node/nodeclient/mock_nodeclient"
"github.com/anyproto/any-sync/testutil/anymock"
"github.com/anyproto/any-sync/util/cidutil"
"github.com/anyproto/any-sync/util/crypto"
)
var ctx = context.Background()
func TestAclSpaceClient_StopSharing(t *testing.T) {
t.Run("not empty", func(t *testing.T) {
fx := newFixture(t)
defer fx.finish(t)
cmds := []string{
"a.invite::invId",
"b.join::invId",
"c.join::invId",
"a.approve::c,r",
}
for _, cmd := range cmds {
err := fx.exec.Execute(cmd)
require.NoError(t, err)
}
newPrivKey, _, err := crypto.GenerateRandomEd25519KeyPair()
require.NoError(t, err)
st := fx.acl.AclState()
require.False(t, st.IsEmpty())
fx.nodeClient.EXPECT().AclAddRecord(ctx, fx.spaceState.SpaceId, gomock.Any()).DoAndReturn(
func(ctx context.Context, spaceId string, rec *consensusproto.RawRecord) (*consensusproto.RawRecordWithId, error) {
return marshallRecord(t, rec), nil
})
err = fx.StopSharing(ctx, list.ReadKeyChangePayload{
MetadataKey: newPrivKey,
ReadKey: crypto.NewAES(),
})
st = fx.acl.AclState()
require.True(t, st.IsEmpty())
})
t.Run("already empty", func(t *testing.T) {
fx := newFixture(t)
defer fx.finish(t)
newPrivKey, _, err := crypto.GenerateRandomEd25519KeyPair()
require.NoError(t, err)
st := fx.acl.AclState()
require.True(t, st.IsEmpty())
err = fx.StopSharing(ctx, list.ReadKeyChangePayload{
MetadataKey: newPrivKey,
ReadKey: crypto.NewAES(),
})
st = fx.acl.AclState()
require.True(t, st.IsEmpty())
})
}
type namedAcl struct {
list.AclList
}
func (a *namedAcl) Name() string {
return syncacl.CName
}
func (a *namedAcl) Init(app *app.App) error {
return nil
}
func marshallRecord(t *testing.T, rec *consensusproto.RawRecord) *consensusproto.RawRecordWithId {
data, err := rec.Marshal()
require.NoError(t, err)
recId, err := cidutil.NewCidFromBytes(data)
require.NoError(t, err)
return &consensusproto.RawRecordWithId{
Payload: data,
Id: recId,
}
}
type fixture struct {
*aclSpaceClient
a *app.App
ctrl *gomock.Controller
nodeClient *mock_nodeclient.MockNodeClient
acl list.AclList
spaceState *spacestate.SpaceState
exec *list.AclTestExecutor
}
func newFixture(t *testing.T) *fixture {
ctrl := gomock.NewController(t)
spaceId := "spaceId"
exec := list.NewAclExecutor(spaceId)
err := exec.Execute("a.init::a")
require.NoError(t, err)
acl := exec.ActualAccounts()["a"].Acl
fx := &fixture{
aclSpaceClient: NewAclSpaceClient().(*aclSpaceClient),
ctrl: ctrl,
acl: acl,
nodeClient: mock_nodeclient.NewMockNodeClient(ctrl),
spaceState: &spacestate.SpaceState{SpaceId: spaceId},
a: new(app.App),
exec: exec,
}
anymock.ExpectComp(fx.nodeClient.EXPECT(), nodeclient.CName)
fx.a.Register(fx.spaceState).
Register(fx.nodeClient).
Register(&namedAcl{acl}).
Register(fx)
require.NoError(t, fx.a.Start(ctx))
return fx
}
func (fx *fixture) finish(t *testing.T) {
require.NoError(t, fx.a.Close(ctx))
fx.ctrl.Finish()
}

View file

@ -0,0 +1,350 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/anyproto/any-sync/commonspace/acl/aclclient (interfaces: AclJoiningClient,AclSpaceClient)
//
// Generated by this command:
//
// mockgen -destination mock_aclclient/mock_aclclient.go github.com/anyproto/any-sync/commonspace/acl/aclclient AclJoiningClient,AclSpaceClient
//
// Package mock_aclclient is a generated GoMock package.
package mock_aclclient
import (
context "context"
reflect "reflect"
app "github.com/anyproto/any-sync/app"
list "github.com/anyproto/any-sync/commonspace/object/acl/list"
consensusproto "github.com/anyproto/any-sync/consensus/consensusproto"
crypto "github.com/anyproto/any-sync/util/crypto"
gomock "go.uber.org/mock/gomock"
)
// MockAclJoiningClient is a mock of AclJoiningClient interface.
type MockAclJoiningClient struct {
ctrl *gomock.Controller
recorder *MockAclJoiningClientMockRecorder
}
// MockAclJoiningClientMockRecorder is the mock recorder for MockAclJoiningClient.
type MockAclJoiningClientMockRecorder struct {
mock *MockAclJoiningClient
}
// NewMockAclJoiningClient creates a new mock instance.
func NewMockAclJoiningClient(ctrl *gomock.Controller) *MockAclJoiningClient {
mock := &MockAclJoiningClient{ctrl: ctrl}
mock.recorder = &MockAclJoiningClientMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockAclJoiningClient) EXPECT() *MockAclJoiningClientMockRecorder {
return m.recorder
}
// AclGetRecords mocks base method.
func (m *MockAclJoiningClient) AclGetRecords(arg0 context.Context, arg1, arg2 string) ([]*consensusproto.RawRecordWithId, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AclGetRecords", arg0, arg1, arg2)
ret0, _ := ret[0].([]*consensusproto.RawRecordWithId)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AclGetRecords indicates an expected call of AclGetRecords.
func (mr *MockAclJoiningClientMockRecorder) AclGetRecords(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AclGetRecords", reflect.TypeOf((*MockAclJoiningClient)(nil).AclGetRecords), arg0, arg1, arg2)
}
// CancelJoin mocks base method.
func (m *MockAclJoiningClient) CancelJoin(arg0 context.Context, arg1 string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CancelJoin", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// CancelJoin indicates an expected call of CancelJoin.
func (mr *MockAclJoiningClientMockRecorder) CancelJoin(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelJoin", reflect.TypeOf((*MockAclJoiningClient)(nil).CancelJoin), arg0, arg1)
}
// CancelRemoveSelf mocks base method.
func (m *MockAclJoiningClient) CancelRemoveSelf(arg0 context.Context, arg1 string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CancelRemoveSelf", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// CancelRemoveSelf indicates an expected call of CancelRemoveSelf.
func (mr *MockAclJoiningClientMockRecorder) CancelRemoveSelf(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRemoveSelf", reflect.TypeOf((*MockAclJoiningClient)(nil).CancelRemoveSelf), arg0, arg1)
}
// Init mocks base method.
func (m *MockAclJoiningClient) Init(arg0 *app.App) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Init", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Init indicates an expected call of Init.
func (mr *MockAclJoiningClientMockRecorder) Init(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockAclJoiningClient)(nil).Init), arg0)
}
// Name mocks base method.
func (m *MockAclJoiningClient) Name() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Name")
ret0, _ := ret[0].(string)
return ret0
}
// Name indicates an expected call of Name.
func (mr *MockAclJoiningClientMockRecorder) Name() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockAclJoiningClient)(nil).Name))
}
// RequestJoin mocks base method.
func (m *MockAclJoiningClient) RequestJoin(arg0 context.Context, arg1 string, arg2 list.RequestJoinPayload) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RequestJoin", arg0, arg1, arg2)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// RequestJoin indicates an expected call of RequestJoin.
func (mr *MockAclJoiningClientMockRecorder) RequestJoin(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestJoin", reflect.TypeOf((*MockAclJoiningClient)(nil).RequestJoin), arg0, arg1, arg2)
}
// MockAclSpaceClient is a mock of AclSpaceClient interface.
type MockAclSpaceClient struct {
ctrl *gomock.Controller
recorder *MockAclSpaceClientMockRecorder
}
// MockAclSpaceClientMockRecorder is the mock recorder for MockAclSpaceClient.
type MockAclSpaceClientMockRecorder struct {
mock *MockAclSpaceClient
}
// NewMockAclSpaceClient creates a new mock instance.
func NewMockAclSpaceClient(ctrl *gomock.Controller) *MockAclSpaceClient {
mock := &MockAclSpaceClient{ctrl: ctrl}
mock.recorder = &MockAclSpaceClientMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockAclSpaceClient) EXPECT() *MockAclSpaceClientMockRecorder {
return m.recorder
}
// AcceptRequest mocks base method.
func (m *MockAclSpaceClient) AcceptRequest(arg0 context.Context, arg1 list.RequestAcceptPayload) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AcceptRequest", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// AcceptRequest indicates an expected call of AcceptRequest.
func (mr *MockAclSpaceClientMockRecorder) AcceptRequest(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptRequest", reflect.TypeOf((*MockAclSpaceClient)(nil).AcceptRequest), arg0, arg1)
}
// AddAccounts mocks base method.
func (m *MockAclSpaceClient) AddAccounts(arg0 context.Context, arg1 list.AccountsAddPayload) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AddAccounts", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// AddAccounts indicates an expected call of AddAccounts.
func (mr *MockAclSpaceClientMockRecorder) AddAccounts(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAccounts", reflect.TypeOf((*MockAclSpaceClient)(nil).AddAccounts), arg0, arg1)
}
// AddRecord mocks base method.
func (m *MockAclSpaceClient) AddRecord(arg0 context.Context, arg1 *consensusproto.RawRecord) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AddRecord", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// AddRecord indicates an expected call of AddRecord.
func (mr *MockAclSpaceClientMockRecorder) AddRecord(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRecord", reflect.TypeOf((*MockAclSpaceClient)(nil).AddRecord), arg0, arg1)
}
// CancelRequest mocks base method.
func (m *MockAclSpaceClient) CancelRequest(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CancelRequest", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// CancelRequest indicates an expected call of CancelRequest.
func (mr *MockAclSpaceClientMockRecorder) CancelRequest(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRequest", reflect.TypeOf((*MockAclSpaceClient)(nil).CancelRequest), arg0)
}
// ChangePermissions mocks base method.
func (m *MockAclSpaceClient) ChangePermissions(arg0 context.Context, arg1 list.PermissionChangesPayload) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ChangePermissions", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// ChangePermissions indicates an expected call of ChangePermissions.
func (mr *MockAclSpaceClientMockRecorder) ChangePermissions(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangePermissions", reflect.TypeOf((*MockAclSpaceClient)(nil).ChangePermissions), arg0, arg1)
}
// DeclineRequest mocks base method.
func (m *MockAclSpaceClient) DeclineRequest(arg0 context.Context, arg1 crypto.PubKey) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeclineRequest", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// DeclineRequest indicates an expected call of DeclineRequest.
func (mr *MockAclSpaceClientMockRecorder) DeclineRequest(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeclineRequest", reflect.TypeOf((*MockAclSpaceClient)(nil).DeclineRequest), arg0, arg1)
}
// GenerateInvite mocks base method.
func (m *MockAclSpaceClient) GenerateInvite() (list.InviteResult, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GenerateInvite")
ret0, _ := ret[0].(list.InviteResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GenerateInvite indicates an expected call of GenerateInvite.
func (mr *MockAclSpaceClientMockRecorder) GenerateInvite() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GenerateInvite", reflect.TypeOf((*MockAclSpaceClient)(nil).GenerateInvite))
}
// Init mocks base method.
func (m *MockAclSpaceClient) Init(arg0 *app.App) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Init", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Init indicates an expected call of Init.
func (mr *MockAclSpaceClientMockRecorder) Init(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockAclSpaceClient)(nil).Init), arg0)
}
// Name mocks base method.
func (m *MockAclSpaceClient) Name() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Name")
ret0, _ := ret[0].(string)
return ret0
}
// Name indicates an expected call of Name.
func (mr *MockAclSpaceClientMockRecorder) Name() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockAclSpaceClient)(nil).Name))
}
// RemoveAccounts mocks base method.
func (m *MockAclSpaceClient) RemoveAccounts(arg0 context.Context, arg1 list.AccountRemovePayload) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RemoveAccounts", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// RemoveAccounts indicates an expected call of RemoveAccounts.
func (mr *MockAclSpaceClientMockRecorder) RemoveAccounts(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveAccounts", reflect.TypeOf((*MockAclSpaceClient)(nil).RemoveAccounts), arg0, arg1)
}
// RequestSelfRemove mocks base method.
func (m *MockAclSpaceClient) RequestSelfRemove(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RequestSelfRemove", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// RequestSelfRemove indicates an expected call of RequestSelfRemove.
func (mr *MockAclSpaceClientMockRecorder) RequestSelfRemove(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestSelfRemove", reflect.TypeOf((*MockAclSpaceClient)(nil).RequestSelfRemove), arg0)
}
// RevokeAllInvites mocks base method.
func (m *MockAclSpaceClient) RevokeAllInvites(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RevokeAllInvites", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// RevokeAllInvites indicates an expected call of RevokeAllInvites.
func (mr *MockAclSpaceClientMockRecorder) RevokeAllInvites(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevokeAllInvites", reflect.TypeOf((*MockAclSpaceClient)(nil).RevokeAllInvites), arg0)
}
// RevokeInvite mocks base method.
func (m *MockAclSpaceClient) RevokeInvite(arg0 context.Context, arg1 string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RevokeInvite", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// RevokeInvite indicates an expected call of RevokeInvite.
func (mr *MockAclSpaceClientMockRecorder) RevokeInvite(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevokeInvite", reflect.TypeOf((*MockAclSpaceClient)(nil).RevokeInvite), arg0, arg1)
}
// StopSharing mocks base method.
func (m *MockAclSpaceClient) StopSharing(arg0 context.Context, arg1 list.ReadKeyChangePayload) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "StopSharing", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// StopSharing indicates an expected call of StopSharing.
func (mr *MockAclSpaceClientMockRecorder) StopSharing(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopSharing", reflect.TypeOf((*MockAclSpaceClient)(nil).StopSharing), arg0, arg1)
}

View file

@ -3,6 +3,12 @@ package commonspace
import (
"context"
"fmt"
"math/rand"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/anyproto/any-sync/commonspace/object/accountdata"
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
@ -12,10 +18,6 @@ import (
"github.com/anyproto/any-sync/commonspace/spacestorage"
"github.com/anyproto/any-sync/commonspace/spacesyncproto"
"github.com/anyproto/any-sync/util/crypto"
"github.com/stretchr/testify/require"
"math/rand"
"testing"
"time"
)
func addIncorrectSnapshot(settingsObject settings.SettingsObject, acc *accountdata.AccountKeys, partialIds map[string]struct{}, newId string) (err error) {

View file

@ -19,13 +19,13 @@ import (
headsync "github.com/anyproto/any-sync/commonspace/headsync"
syncacl "github.com/anyproto/any-sync/commonspace/object/acl/syncacl"
treesyncer "github.com/anyproto/any-sync/commonspace/object/treesyncer"
objectsync "github.com/anyproto/any-sync/commonspace/objectsync"
objecttreebuilder "github.com/anyproto/any-sync/commonspace/objecttreebuilder"
spacestorage "github.com/anyproto/any-sync/commonspace/spacestorage"
spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto"
syncstatus "github.com/anyproto/any-sync/commonspace/syncstatus"
peer "github.com/anyproto/any-sync/net/peer"
gomock "go.uber.org/mock/gomock"
drpc "storj.io/drpc"
)
// MockSpace is a mock of Space interface.
@ -151,20 +151,6 @@ func (mr *MockSpaceMockRecorder) GetNodePeers(arg0 any) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNodePeers", reflect.TypeOf((*MockSpace)(nil).GetNodePeers), arg0)
}
// HandleMessage mocks base method.
func (m *MockSpace) HandleMessage(arg0 context.Context, arg1 objectsync.HandleMessage) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HandleMessage", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// HandleMessage indicates an expected call of HandleMessage.
func (mr *MockSpaceMockRecorder) HandleMessage(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMessage", reflect.TypeOf((*MockSpace)(nil).HandleMessage), arg0, arg1)
}
// HandleRangeRequest mocks base method.
func (m *MockSpace) HandleRangeRequest(arg0 context.Context, arg1 *spacesyncproto.HeadSyncRequest) (*spacesyncproto.HeadSyncResponse, error) {
m.ctrl.T.Helper()
@ -180,19 +166,32 @@ func (mr *MockSpaceMockRecorder) HandleRangeRequest(arg0, arg1 any) *gomock.Call
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleRangeRequest", reflect.TypeOf((*MockSpace)(nil).HandleRangeRequest), arg0, arg1)
}
// HandleSyncRequest mocks base method.
func (m *MockSpace) HandleSyncRequest(arg0 context.Context, arg1 *spacesyncproto.ObjectSyncMessage) (*spacesyncproto.ObjectSyncMessage, error) {
// HandleStream mocks base method.
func (m *MockSpace) HandleStream(arg0 spacesyncproto.DRPCSpaceSync_ObjectSyncStreamStream) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HandleSyncRequest", arg0, arg1)
ret0, _ := ret[0].(*spacesyncproto.ObjectSyncMessage)
ret1, _ := ret[1].(error)
return ret0, ret1
ret := m.ctrl.Call(m, "HandleStream", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// HandleSyncRequest indicates an expected call of HandleSyncRequest.
func (mr *MockSpaceMockRecorder) HandleSyncRequest(arg0, arg1 any) *gomock.Call {
// HandleStream indicates an expected call of HandleStream.
func (mr *MockSpaceMockRecorder) HandleStream(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleSyncRequest", reflect.TypeOf((*MockSpace)(nil).HandleSyncRequest), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleStream", reflect.TypeOf((*MockSpace)(nil).HandleStream), arg0)
}
// HandleStreamSyncRequest mocks base method.
func (m *MockSpace) HandleStreamSyncRequest(arg0 context.Context, arg1 *spacesyncproto.ObjectSyncMessage, arg2 drpc.Stream) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HandleStreamSyncRequest", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// HandleStreamSyncRequest indicates an expected call of HandleStreamSyncRequest.
func (mr *MockSpaceMockRecorder) HandleStreamSyncRequest(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleStreamSyncRequest", reflect.TypeOf((*MockSpace)(nil).HandleStreamSyncRequest), arg0, arg1, arg2)
}
// Id mocks base method.

View file

@ -34,6 +34,7 @@ var (
ErrIncorrectRoot = errors.New("incorrect root")
ErrIncorrectRecordSequence = errors.New("incorrect prev id of a record")
ErrMetadataTooLarge = errors.New("metadata size too large")
ErrOwnerNotFound = errors.New("owner not found")
)
const MaxMetadataLen = 1024
@ -228,6 +229,16 @@ func (st *AclState) ApplyRecord(record *AclRecord) (err error) {
return
}
func (st *AclState) IsEmpty() bool {
users := 0
for _, acc := range st.CurrentAccounts() {
if !acc.Permissions.NoPermissions() {
users++
}
}
return users == 1 && len(st.Invites()) == 0 && len(st.pendingRequests) == 0
}
func (st *AclState) applyRoot(record *AclRecord) (err error) {
root, ok := record.Model.(*aclrecordproto.AclRoot)
if !ok {
@ -844,6 +855,15 @@ func (st *AclState) LastRecordId() string {
return st.lastRecordId
}
func (st *AclState) OwnerPubKey() (ownerIdentity crypto.PubKey, err error) {
for _, aState := range st.accountStates {
if aState.Permissions.IsOwner() {
return aState.PubKey, nil
}
}
return nil, ErrOwnerNotFound
}
func (st *AclState) deriveKey() (crypto.SymKey, error) {
keyBytes, err := st.key.Raw()
if err != nil {

View file

@ -0,0 +1,70 @@
package list
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestAclStateIsEmpty(t *testing.T) {
t.Run("not empty when invites", func(t *testing.T) {
a := NewAclExecutor("spaceId")
cmds := []string{
"a.init::a",
"a.invite::invId",
}
for _, cmd := range cmds {
err := a.Execute(cmd)
require.NoError(t, err)
}
st := a.ActualAccounts()["a"].Acl.AclState()
require.False(t, st.IsEmpty())
})
t.Run("not empty when joining requests", func(t *testing.T) {
a := NewAclExecutor("spaceId")
cmds := []string{
"a.init::a",
"a.invite::invId",
"b.join::invId",
"a.revoke::invId",
}
for _, cmd := range cmds {
err := a.Execute(cmd)
require.NoError(t, err)
}
st := a.ActualAccounts()["a"].Acl.AclState()
require.False(t, st.IsEmpty())
})
t.Run("not empty when users", func(t *testing.T) {
a := NewAclExecutor("spaceId")
cmds := []string{
"a.init::a",
"a.invite::invId",
"b.join::invId",
"a.revoke::invId",
"a.approve::b,r",
}
for _, cmd := range cmds {
err := a.Execute(cmd)
require.NoError(t, err)
}
st := a.ActualAccounts()["a"].Acl.AclState()
require.False(t, st.IsEmpty())
})
t.Run("empty when no joining requests, no invites and no users", func(t *testing.T) {
a := NewAclExecutor("spaceId")
cmds := []string{
"a.init::a",
"a.invite::invId",
"b.join::invId",
"a.decline::b",
"a.revoke::invId",
}
for _, cmd := range cmds {
err := a.Execute(cmd)
require.NoError(t, err)
}
st := a.ActualAccounts()["a"].Acl.AclState()
require.True(t, st.IsEmpty())
})
}

View file

@ -4,6 +4,7 @@ import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anyproto/any-sync/commonspace/object/accountdata"
@ -395,3 +396,10 @@ func TestAclList_RequestRemove(t *testing.T) {
require.Nil(t, accountState().keys[removeRec.Id].ReadKey)
require.NotEmpty(t, accountState().keys[fx.ownerAcl.Id()])
}
func TestAclState_OwnerPubKey(t *testing.T) {
fx := newFixture(t)
pubKey, err := fx.ownerAcl.AclState().OwnerPubKey()
require.NoError(t, err)
assert.Equal(t, fx.ownerKeys.SignKey.GetPublic().Account(), pubKey.Account())
}

View file

@ -1,6 +1,8 @@
package list
import (
"fmt"
"github.com/anyproto/any-sync/commonspace/object/accountdata"
"github.com/anyproto/any-sync/commonspace/object/acl/liststorage"
"github.com/anyproto/any-sync/consensus/consensusproto"
@ -53,3 +55,30 @@ func NewTestAclWithRoot(keys *accountdata.AccountKeys, root *consensusproto.RawR
}
return BuildAclListWithIdentity(keys, st, NoOpAcceptorVerifier{})
}
func NewTestAclStateWithUsers(numWriters, numReaders, numInvites int) *AclState {
st := &AclState{
keys: make(map[string]AclKeys),
accountStates: make(map[string]AccountState),
inviteKeys: make(map[string]crypto.PubKey),
requestRecords: make(map[string]RequestRecord),
pendingRequests: make(map[string]string),
keyStore: crypto.NewKeyStorage(),
}
for i := 0; i < numWriters; i++ {
st.accountStates[fmt.Sprint("w", i)] = AccountState{
Permissions: AclPermissionsWriter,
Status: StatusActive,
}
}
for i := 0; i < numReaders; i++ {
st.accountStates[fmt.Sprint("r", i)] = AccountState{
Permissions: AclPermissionsReader,
Status: StatusActive,
}
}
for i := 0; i < numInvites; i++ {
st.inviteKeys[fmt.Sprint("r", i)] = nil
}
return st
}

View file

@ -5,6 +5,7 @@
//
// mockgen -destination mock_syncacl/mock_syncacl.go github.com/anyproto/any-sync/commonspace/object/acl/syncacl SyncAcl,SyncClient,RequestFactory,AclSyncProtocol
//
// Package mock_syncacl is a generated GoMock package.
package mock_syncacl

View file

@ -9,8 +9,8 @@ import (
)
type DataConverter interface {
Unmarshall(decrypted []byte) (any, error)
Marshall(model any) ([]byte, error)
Unmarshall(dataType string, decrypted []byte) (any, error)
Marshall(model any) (data []byte, dataType string, err error)
}
type TreeExporterParams struct {
@ -59,21 +59,25 @@ func (t *treeExporter) ExportUnencrypted(tree objecttree.ReadableObjectTree) (er
}
err = tree.IterateRoot(
func(change *objecttree.Change, decrypted []byte) (any, error) {
return t.converter.Unmarshall(decrypted)
return t.converter.Unmarshall(change.DataType, decrypted)
},
func(change *objecttree.Change) bool {
if change.Id == tree.Id() {
err = putStorage(change)
return err == nil
}
var data []byte
data, err = t.converter.Marshall(change.Model)
var (
data []byte
dataType string
)
data, dataType, err = t.converter.Marshall(change.Model)
if err != nil {
return false
}
// that means that change is unencrypted
change.ReadKeyId = ""
change.Data = data
change.DataType = dataType
err = putStorage(change)
return err == nil
})

View file

@ -333,30 +333,6 @@ func (mr *MockObjectTreeMockRecorder) PrepareChange(arg0 any) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrepareChange", reflect.TypeOf((*MockObjectTree)(nil).PrepareChange), arg0)
}
// RLock mocks base method.
func (m *MockObjectTree) RLock() {
m.ctrl.T.Helper()
m.ctrl.Call(m, "RLock")
}
// RLock indicates an expected call of RLock.
func (mr *MockObjectTreeMockRecorder) RLock() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RLock", reflect.TypeOf((*MockObjectTree)(nil).RLock))
}
// RUnlock mocks base method.
func (m *MockObjectTree) RUnlock() {
m.ctrl.T.Helper()
m.ctrl.Call(m, "RUnlock")
}
// RUnlock indicates an expected call of RUnlock.
func (mr *MockObjectTreeMockRecorder) RUnlock() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RUnlock", reflect.TypeOf((*MockObjectTree)(nil).RUnlock))
}
// Root mocks base method.
func (m *MockObjectTree) Root() *objecttree.Change {
m.ctrl.T.Helper()
@ -428,20 +404,6 @@ func (mr *MockObjectTreeMockRecorder) TryLock() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TryLock", reflect.TypeOf((*MockObjectTree)(nil).TryLock))
}
// TryRLock mocks base method.
func (m *MockObjectTree) TryRLock() bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "TryRLock")
ret0, _ := ret[0].(bool)
return ret0
}
// TryRLock indicates an expected call of TryRLock.
func (mr *MockObjectTreeMockRecorder) TryRLock() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TryRLock", reflect.TypeOf((*MockObjectTree)(nil).TryRLock))
}
// Unlock mocks base method.
func (m *MockObjectTree) Unlock() {
m.ctrl.T.Helper()

View file

@ -4,31 +4,29 @@ package objecttree
import (
"context"
"errors"
"fmt"
"sync"
"time"
"github.com/anyproto/any-sync/util/crypto"
"github.com/anyproto/any-sync/util/debug"
"go.uber.org/zap"
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
"github.com/anyproto/any-sync/util/crypto"
"github.com/anyproto/any-sync/util/slice"
)
type RWLocker interface {
sync.Locker
RLock()
RUnlock()
TryRLock() bool
TryLock() bool
}
var (
ErrHasInvalidChanges = errors.New("the change is invalid")
ErrNoCommonSnapshot = errors.New("trees doesn't have a common snapshot")
ErrNoChangeInTree = errors.New("no such change in tree")
ErrMissingKey = errors.New("missing current read key")
ErrDerived = errors.New("expect >= 2 changes in derived tree")
ErrDeleted = errors.New("object tree is deleted")
ErrNoAclHead = errors.New("no acl head")
)
type AddResultSummary int
@ -49,8 +47,13 @@ type RawChangesPayload struct {
type ChangeIterateFunc = func(change *Change) bool
type ChangeConvertFunc = func(change *Change, decrypted []byte) (any, error)
type TryLocker interface {
sync.Locker
TryLock() bool
}
type ReadableObjectTree interface {
RWLocker
TryLocker
Id() string
Header() *treechangeproto.RawTreeChangeWithId
@ -106,6 +109,7 @@ type objectTree struct {
keys map[string]crypto.SymKey
currentReadKey crypto.SymKey
isDeleted bool
// buffers
difSnapshotBuf []*treechangeproto.RawTreeChangeWithId
@ -115,7 +119,7 @@ type objectTree struct {
snapshotPath []string
sync.RWMutex
sync.Mutex
}
func (ot *objectTree) rebuildFromStorage(theirHeads []string, newChanges []*Change) (err error) {
@ -123,6 +127,7 @@ func (ot *objectTree) rebuildFromStorage(theirHeads []string, newChanges []*Chan
ot.treeBuilder.Reset()
ot.tree, err = ot.treeBuilder.Build(theirHeads, newChanges)
if err != nil {
ot.tree = oldTree
return
}
@ -180,13 +185,29 @@ func (ot *objectTree) Storage() treestorage.TreeStorage {
}
func (ot *objectTree) GetChange(id string) (*Change, error) {
if ot.isDeleted {
return nil, ErrDeleted
}
if ch, ok := ot.tree.attached[id]; ok {
return ch, nil
}
return nil, ErrNoChangeInTree
}
func (ot *objectTree) logUseWhenUnlocked() {
// this is needed to check when we use the tree not under the lock
if ot.TryLock() {
log.With(zap.String("treeId", ot.id), zap.String("stack", debug.StackCompact(true))).Error("use tree when unlocked")
ot.Unlock()
}
}
func (ot *objectTree) AddContent(ctx context.Context, content SignableChangeContent) (res AddResult, err error) {
if ot.isDeleted {
err = ErrDeleted
return
}
ot.logUseWhenUnlocked()
payload, err := ot.prepareBuilderContent(content)
if err != nil {
return
@ -228,6 +249,10 @@ func (ot *objectTree) AddContent(ctx context.Context, content SignableChangeCont
}
func (ot *objectTree) UnpackChange(raw *treechangeproto.RawTreeChangeWithId) (data []byte, err error) {
if ot.isDeleted {
err = ErrDeleted
return
}
unmarshalled, err := ot.changeBuilder.Unmarshall(raw, true)
if err != nil {
return
@ -237,6 +262,10 @@ func (ot *objectTree) UnpackChange(raw *treechangeproto.RawTreeChangeWithId) (da
}
func (ot *objectTree) PrepareChange(content SignableChangeContent) (res *treechangeproto.RawTreeChangeWithId, err error) {
if ot.isDeleted {
err = ErrDeleted
return
}
payload, err := ot.prepareBuilderContent(content)
if err != nil {
return
@ -292,6 +321,11 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt
}
func (ot *objectTree) AddRawChanges(ctx context.Context, changesPayload RawChangesPayload) (addResult AddResult, err error) {
if ot.isDeleted {
err = ErrDeleted
return
}
ot.logUseWhenUnlocked()
lastHeadId := ot.tree.lastIteratedHeadId
addResult, err = ot.addRawChanges(ctx, changesPayload)
if err != nil {
@ -309,7 +343,10 @@ func (ot *objectTree) AddRawChanges(ctx context.Context, changesPayload RawChang
err = ot.treeStorage.AddRawChangesSetHeads(addResult.Added, addResult.Heads)
if err != nil {
// rolling back all changes made to inmemory state
ot.rebuildFromStorage(nil, nil)
rebuildErr := ot.rebuildFromStorage(nil, nil)
if rebuildErr != nil {
log.Error("failed to rebuild after adding to storage", zap.Strings("heads", ot.Heads()), zap.Error(rebuildErr))
}
}
return
}
@ -372,7 +409,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, changesPayload RawChang
headsToUse = changesPayload.NewHeads
)
// if our validator provides filtering mechanism then we use it
filteredHeads, ot.newChangesBuf, ot.newSnapshotsBuf, ot.notSeenIdxBuf = ot.validator.FilterChanges(ot.aclList, changesPayload.NewHeads, ot.newChangesBuf, ot.newSnapshotsBuf, ot.notSeenIdxBuf)
filteredHeads, ot.newChangesBuf, ot.newSnapshotsBuf, ot.notSeenIdxBuf = ot.validator.FilterChanges(ot.aclList, ot.newChangesBuf, ot.newSnapshotsBuf, ot.notSeenIdxBuf)
if filteredHeads {
// if we filtered some of the heads, then we don't know which heads to use
headsToUse = []string{}
@ -409,20 +446,27 @@ func (ot *objectTree) addRawChanges(ctx context.Context, changesPayload RawChang
break
}
}
log := log.With(zap.String("treeId", ot.id))
if shouldRebuildFromStorage {
err = ot.rebuildFromStorage(headsToUse, ot.newChangesBuf)
if err != nil {
log.Error("failed to rebuild with new heads", zap.Strings("headsToUse", headsToUse), zap.Error(err))
// rebuilding without new changes
ot.rebuildFromStorage(nil, nil)
rebuildErr := ot.rebuildFromStorage(nil, nil)
if rebuildErr != nil {
log.Error("failed to rebuild from storage", zap.Strings("heads", ot.Heads()), zap.Error(rebuildErr))
}
return
}
addResult, err = ot.createAddResult(prevHeadsCopy, Rebuild, nil, changesPayload.RawChanges)
if err != nil {
log.Error("failed to create add result", zap.Strings("headsToUse", headsToUse), zap.Error(err))
// that means that some unattached changes were somehow corrupted in memory
// this shouldn't happen but if that happens, then rebuilding from storage
ot.rebuildFromStorage(nil, nil)
return
rebuildErr := ot.rebuildFromStorage(nil, nil)
if rebuildErr != nil {
log.Error("failed to rebuild after add result", zap.Strings("heads", ot.Heads()), zap.Error(rebuildErr))
}
}
return
}
@ -443,14 +487,18 @@ func (ot *objectTree) addRawChanges(ctx context.Context, changesPayload RawChang
err = ot.validateTree(treeChangesAdded)
if err != nil {
rollback(treeChangesAdded)
err = ErrHasInvalidChanges
err = fmt.Errorf("%w: %w", ErrHasInvalidChanges, err)
return
}
addResult, err = ot.createAddResult(prevHeadsCopy, mode, treeChangesAdded, changesPayload.RawChanges)
if err != nil {
// that means that some unattached changes were somehow corrupted in memory
// this shouldn't happen but if that happens, then rebuilding from storage
ot.rebuildFromStorage(nil, nil)
rollback(treeChangesAdded)
rebuildErr := ot.rebuildFromStorage(nil, nil)
if rebuildErr != nil {
log.Error("failed to rebuild after add result (add to tree)", zap.Strings("heads", ot.Heads()), zap.Error(rebuildErr))
}
return
}
return
@ -527,6 +575,10 @@ func (ot *objectTree) IterateRoot(convert ChangeConvertFunc, iterate ChangeItera
}
func (ot *objectTree) IterateFrom(id string, convert ChangeConvertFunc, iterate ChangeIterateFunc) (err error) {
if ot.isDeleted {
err = ErrDeleted
return
}
if convert == nil {
ot.tree.Iterate(id, iterate)
return
@ -576,12 +628,14 @@ func (ot *objectTree) IterateFrom(id string, convert ChangeConvertFunc, iterate
}
func (ot *objectTree) HasChanges(chs ...string) bool {
if ot.isDeleted {
return false
}
for _, ch := range chs {
if _, attachedExists := ot.tree.attached[ch]; !attachedExists {
return false
}
}
return true
}
@ -602,10 +656,17 @@ func (ot *objectTree) Close() error {
}
func (ot *objectTree) Delete() error {
if ot.isDeleted {
return nil
}
ot.isDeleted = true
return ot.treeStorage.Delete()
}
func (ot *objectTree) SnapshotPath() []string {
if ot.isDeleted {
return nil
}
// TODO: Add error as return parameter
if ot.snapshotPathIsActual() {
return ot.snapshotPath
@ -628,6 +689,9 @@ func (ot *objectTree) SnapshotPath() []string {
}
func (ot *objectTree) ChangesAfterCommonSnapshot(theirPath, theirHeads []string) ([]*treechangeproto.RawTreeChangeWithId, error) {
if ot.isDeleted {
return nil, ErrDeleted
}
var (
needFullDocument = len(theirPath) == 0
ourPath = ot.SnapshotPath()

View file

@ -2,6 +2,7 @@ package objecttree
import (
"context"
"errors"
"fmt"
"math/rand"
"testing"
@ -15,6 +16,7 @@ import (
"github.com/anyproto/any-sync/commonspace/object/accountdata"
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/commonspace/object/acl/liststorage"
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
)
@ -212,6 +214,51 @@ func TestObjectTree(t *testing.T) {
aclList, keys := prepareAclList(t)
ctx := context.Background()
t.Run("delete object tree", func(t *testing.T) {
exec := list.NewAclExecutor("spaceId")
type cmdErr struct {
cmd string
err error
}
cmds := []cmdErr{
{"a.init::a", nil},
}
for _, cmd := range cmds {
err := exec.Execute(cmd.cmd)
require.Equal(t, cmd.err, err, cmd)
}
aAccount := exec.ActualAccounts()["a"]
root, err := CreateObjectTreeRoot(ObjectTreeCreatePayload{
PrivKey: aAccount.Keys.SignKey,
ChangeType: "changeType",
ChangePayload: nil,
SpaceId: "spaceId",
IsEncrypted: true,
}, aAccount.Acl)
require.NoError(t, err)
aStore, _ := treestorage.NewInMemoryTreeStorage(root, []string{root.Id}, []*treechangeproto.RawTreeChangeWithId{root})
aTree, err := BuildKeyFilterableObjectTree(aStore, aAccount.Acl)
require.NoError(t, err)
err = aTree.Delete()
require.NoError(t, err)
_, err = aTree.ChangesAfterCommonSnapshot(nil, nil)
require.Equal(t, ErrDeleted, err)
err = aTree.IterateFrom("", nil, func(change *Change) bool {
return true
})
require.Equal(t, ErrDeleted, err)
_, err = aTree.AddContent(ctx, SignableChangeContent{})
require.Equal(t, ErrDeleted, err)
_, err = aTree.AddRawChanges(ctx, RawChangesPayload{})
require.Equal(t, ErrDeleted, err)
_, err = aTree.PrepareChange(SignableChangeContent{})
require.Equal(t, ErrDeleted, err)
_, err = aTree.UnpackChange(nil)
require.Equal(t, ErrDeleted, err)
_, err = aTree.GetChange("")
require.Equal(t, ErrDeleted, err)
})
t.Run("user delete logic: validation, key change, decryption", func(t *testing.T) {
exec := list.NewAclExecutor("spaceId")
type cmdErr struct {
@ -286,6 +333,84 @@ func TestObjectTree(t *testing.T) {
require.NoError(t, err)
})
t.Run("filter changes when no aclHeadId", func(t *testing.T) {
exec := list.NewAclExecutor("spaceId")
type cmdErr struct {
cmd string
err error
}
cmds := []cmdErr{
{"a.init::a", nil},
{"a.invite::invId", nil},
{"b.join::invId", nil},
{"a.approve::b,r", nil},
}
for _, cmd := range cmds {
err := exec.Execute(cmd.cmd)
require.Equal(t, cmd.err, err, cmd)
}
aAccount := exec.ActualAccounts()["a"]
bAccount := exec.ActualAccounts()["b"]
root, err := CreateObjectTreeRoot(ObjectTreeCreatePayload{
PrivKey: aAccount.Keys.SignKey,
ChangeType: "changeType",
ChangePayload: nil,
SpaceId: "spaceId",
IsEncrypted: true,
}, aAccount.Acl)
require.NoError(t, err)
aStore, _ := treestorage.NewInMemoryTreeStorage(root, []string{root.Id}, []*treechangeproto.RawTreeChangeWithId{root})
aTree, err := BuildKeyFilterableObjectTree(aStore, aAccount.Acl)
require.NoError(t, err)
_, err = aTree.AddContent(ctx, SignableChangeContent{
Data: []byte("some"),
Key: aAccount.Keys.SignKey,
IsSnapshot: false,
IsEncrypted: true,
DataType: mockDataType,
})
require.NoError(t, err)
bStore := aTree.Storage().(*treestorage.InMemoryTreeStorage).Copy()
// copying old version of storage
prevAclRecs, err := bAccount.Acl.RecordsAfter(ctx, "")
require.NoError(t, err)
storage, err := liststorage.NewInMemoryAclListStorage(prevAclRecs[0].Id, prevAclRecs)
require.NoError(t, err)
acl, err := list.BuildAclListWithIdentity(bAccount.Keys, storage, list.NoOpAcceptorVerifier{})
require.NoError(t, err)
// creating tree with old storage which doesn't have a new invite record
bTree, err := BuildKeyFilterableObjectTree(bStore, acl)
require.NoError(t, err)
err = exec.Execute("a.invite::inv1Id")
require.NoError(t, err)
res, err := aTree.AddContent(ctx, SignableChangeContent{
Data: []byte("some"),
Key: aAccount.Keys.SignKey,
IsSnapshot: false,
IsEncrypted: true,
DataType: mockDataType,
})
unexpectedId := res.Added[0].Id
require.NoError(t, err)
var collectedChanges []*Change
err = aTree.IterateRoot(func(change *Change, decrypted []byte) (any, error) {
return nil, nil
}, func(change *Change) bool {
collectedChanges = append(collectedChanges, change)
return true
})
require.NoError(t, err)
bObjTree := bTree.(*objectTree)
// this is just a random slice, so the func works
indexes := []int{1, 2, 3, 4, 5}
// checking that we filter the changes
filtered, filteredChanges, _, _ := bObjTree.validator.FilterChanges(bObjTree.aclList, collectedChanges, nil, indexes)
require.True(t, filtered)
for _, ch := range filteredChanges {
require.NotEqual(t, unexpectedId, ch.Id)
}
})
t.Run("add content", func(t *testing.T) {
root, err := CreateObjectTreeRoot(ObjectTreeCreatePayload{
PrivKey: keys.SignKey,
@ -1274,7 +1399,7 @@ func TestObjectTree(t *testing.T) {
Heads: []string{"3"},
Changes: rawChanges,
}, ctx.aclList)
require.Equal(t, ErrHasInvalidChanges, err)
require.True(t, errors.Is(err, ErrHasInvalidChanges))
})
t.Run("gen changes test load iterator simple", func(t *testing.T) {

View file

@ -16,7 +16,7 @@ type ObjectTreeValidator interface {
ValidateFullTree(tree *Tree, aclList list.AclList) error
// ValidateNewChanges should always be entered while holding a read lock on AclList
ValidateNewChanges(tree *Tree, aclList list.AclList, newChanges []*Change) error
FilterChanges(aclList list.AclList, heads []string, changes []*Change, snapshots []*Change, indexes []int) (filteredHeads bool, filtered, filteredSnapshots []*Change, newIndexes []int)
FilterChanges(aclList list.AclList, changes []*Change, snapshots []*Change, indexes []int) (filteredHeads bool, filtered, filteredSnapshots []*Change, newIndexes []int)
}
type noOpTreeValidator struct {
@ -31,7 +31,7 @@ func (n *noOpTreeValidator) ValidateNewChanges(tree *Tree, aclList list.AclList,
return nil
}
func (n *noOpTreeValidator) FilterChanges(aclList list.AclList, heads []string, changes []*Change, snapshots []*Change, indexes []int) (filteredHeads bool, filtered, filteredSnapshots []*Change, newIndexes []int) {
func (n *noOpTreeValidator) FilterChanges(aclList list.AclList, changes []*Change, snapshots []*Change, indexes []int) (filteredHeads bool, filtered, filteredSnapshots []*Change, newIndexes []int) {
if n.filterFunc == nil {
return false, changes, snapshots, indexes
}
@ -80,7 +80,7 @@ func (v *objectTreeValidator) ValidateNewChanges(tree *Tree, aclList list.AclLis
return
}
func (v *objectTreeValidator) FilterChanges(aclList list.AclList, heads []string, changes []*Change, snapshots []*Change, indexes []int) (filteredHeads bool, filtered, filteredSnapshots []*Change, newIndexes []int) {
func (v *objectTreeValidator) FilterChanges(aclList list.AclList, changes []*Change, snapshots []*Change, indexes []int) (filteredHeads bool, filtered, filteredSnapshots []*Change, newIndexes []int) {
if !v.shouldFilter {
return false, changes, snapshots, indexes
}
@ -88,18 +88,25 @@ func (v *objectTreeValidator) FilterChanges(aclList list.AclList, heads []string
defer aclList.RUnlock()
state := aclList.AclState()
for idx, c := range changes {
// only taking changes which we can read
if keys, exists := state.Keys()[c.ReadKeyId]; exists && keys.ReadKey != nil {
// this has to be a root
if c.PreviousIds == nil {
newIndexes = append(newIndexes, indexes[idx])
filtered = append(filtered, c)
filteredSnapshots = append(filteredSnapshots, c)
continue
}
// only taking changes which we can read and for which we have acl heads
if keys, exists := state.Keys()[c.ReadKeyId]; aclList.HasHead(c.AclHeadId) && exists && keys.ReadKey != nil {
newIndexes = append(newIndexes, indexes[idx])
filtered = append(filtered, c)
if c.IsSnapshot {
filteredSnapshots = append(filteredSnapshots, c)
}
} else {
// if we filtered at least one change this can be the change between heads and other changes
// thus we cannot use heads
filteredHeads = true
continue
}
// if we filtered at least one change this can be the change between heads and other changes
// thus we cannot use heads
filteredHeads = true
}
return
}
@ -162,6 +169,8 @@ func ValidateRawTreeBuildFunc(payload treestorage.TreeStorageCreatePayload, buil
if err != nil {
return
}
tree.Lock()
defer tree.Unlock()
res, err := tree.AddRawChanges(context.Background(), RawChangesPayload{
NewHeads: payload.Heads,
RawChanges: payload.Changes,
@ -170,7 +179,7 @@ func ValidateRawTreeBuildFunc(payload treestorage.TreeStorageCreatePayload, buil
return
}
if !slice.UnsortedEquals(res.Heads, payload.Heads) {
return payload, ErrHasInvalidChanges
return payload, fmt.Errorf("heads mismatch: %v != %v, %w", res.Heads, payload.Heads, ErrHasInvalidChanges)
}
// if tree has only one change we still should check if the snapshot id is same as root
if IsEmptyDerivedTree(tree) {
@ -194,6 +203,8 @@ func ValidateFilterRawTree(payload treestorage.TreeStorageCreatePayload, aclList
if err != nil {
return
}
tree.Lock()
defer tree.Unlock()
res, err := tree.AddRawChanges(context.Background(), RawChangesPayload{
NewHeads: payload.Heads,
RawChanges: payload.Changes,

View file

@ -349,30 +349,6 @@ func (mr *MockSyncTreeMockRecorder) PrepareChange(arg0 any) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrepareChange", reflect.TypeOf((*MockSyncTree)(nil).PrepareChange), arg0)
}
// RLock mocks base method.
func (m *MockSyncTree) RLock() {
m.ctrl.T.Helper()
m.ctrl.Call(m, "RLock")
}
// RLock indicates an expected call of RLock.
func (mr *MockSyncTreeMockRecorder) RLock() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RLock", reflect.TypeOf((*MockSyncTree)(nil).RLock))
}
// RUnlock mocks base method.
func (m *MockSyncTree) RUnlock() {
m.ctrl.T.Helper()
m.ctrl.Call(m, "RUnlock")
}
// RUnlock indicates an expected call of RUnlock.
func (mr *MockSyncTreeMockRecorder) RUnlock() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RUnlock", reflect.TypeOf((*MockSyncTree)(nil).RUnlock))
}
// Root mocks base method.
func (m *MockSyncTree) Root() *objecttree.Change {
m.ctrl.T.Helper()
@ -470,20 +446,6 @@ func (mr *MockSyncTreeMockRecorder) TryLock() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TryLock", reflect.TypeOf((*MockSyncTree)(nil).TryLock))
}
// TryRLock mocks base method.
func (m *MockSyncTree) TryRLock() bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "TryRLock")
ret0, _ := ret[0].(bool)
return ret0
}
// TryRLock indicates an expected call of TryRLock.
func (mr *MockSyncTreeMockRecorder) TryRLock() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TryRLock", reflect.TypeOf((*MockSyncTree)(nil).TryRLock))
}
// Unlock mocks base method.
func (m *MockSyncTree) Unlock() {
m.ctrl.T.Helper()

View file

@ -2,18 +2,19 @@ package synctree
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree"
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree"
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener"
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener/mock_updatelistener"
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
"github.com/anyproto/any-sync/commonspace/objectsync"
"github.com/anyproto/any-sync/commonspace/syncstatus"
"github.com/anyproto/any-sync/nodeconf"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"testing"
)
type syncTreeMatcher struct {

View file

@ -3,9 +3,10 @@ package treestorage
import (
"context"
"fmt"
"sync"
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
"github.com/anyproto/any-sync/util/slice"
"sync"
)
type InMemoryTreeStorage struct {
@ -111,6 +112,9 @@ func (t *InMemoryTreeStorage) GetRawChange(ctx context.Context, changeId string)
}
func (t *InMemoryTreeStorage) Delete() error {
t.root = nil
t.Changes = nil
t.heads = nil
return nil
}

View file

@ -114,7 +114,7 @@ func (s *spaceService) CreateSpace(ctx context.Context, payload SpaceCreatePaylo
return
}
return store.Id(), nil
return store.Id(), store.Close(ctx)
}
func (s *spaceService) DeriveId(ctx context.Context, payload SpaceDerivePayload) (id string, err error) {
@ -139,7 +139,7 @@ func (s *spaceService) DeriveSpace(ctx context.Context, payload SpaceDerivePaylo
return
}
return store.Id(), nil
return store.Id(), store.Close(ctx)
}
func (s *spaceService) NewSpace(ctx context.Context, id string, deps Deps) (Space, error) {

View file

@ -186,7 +186,7 @@ func (i *InMemorySpaceStorage) AllTrees() map[string]treestorage.TreeStorage {
defer i.Unlock()
cp := map[string]treestorage.TreeStorage{}
for id, store := range i.trees {
cp[id] = store
cp[id] = store.(*treestorage.InMemoryTreeStorage).Copy()
}
return cp
}

View file

@ -461,6 +461,22 @@ func (t *mockTreeManager) DeleteTree(ctx context.Context, spaceId, treeId string
type mockCoordinatorClient struct {
}
func (m mockCoordinatorClient) StatusCheckMany(ctx context.Context, spaceIds []string) (statuses []*coordinatorproto.SpaceStatusPayload, limits *coordinatorproto.AccountLimits, err error) {
return
}
func (m mockCoordinatorClient) SpaceMakeShareable(ctx context.Context, spaceId string) (err error) {
return
}
func (m mockCoordinatorClient) SpaceMakeUnshareable(ctx context.Context, spaceId, aclId string) (err error) {
return
}
func (m mockCoordinatorClient) AccountLimitsSet(ctx context.Context, req *coordinatorproto.AccountLimitsSetRequest) error {
return nil
}
func (m mockCoordinatorClient) SpaceDelete(ctx context.Context, spaceId string, conf *coordinatorproto.DeletionConfirmPayloadWithSignature) (err error) {
return
}
@ -473,10 +489,6 @@ func (m mockCoordinatorClient) AccountRevertDeletion(ctx context.Context) (err e
return
}
func (m mockCoordinatorClient) StatusCheckMany(ctx context.Context, spaceIds []string) (statuses []*coordinatorproto.SpaceStatusPayload, err error) {
return
}
func (m mockCoordinatorClient) StatusCheck(ctx context.Context, spaceId string) (status *coordinatorproto.SpaceStatusPayload, err error) {
return
}
@ -485,10 +497,6 @@ func (m mockCoordinatorClient) SpaceSign(ctx context.Context, payload coordinato
return
}
func (m mockCoordinatorClient) FileLimitCheck(ctx context.Context, spaceId string, identity []byte) (response *coordinatorproto.FileLimitCheckResponse, err error) {
return
}
func (m mockCoordinatorClient) NetworkConfiguration(ctx context.Context, currentId string) (*coordinatorproto.NetworkConfigurationResponse, error) {
return nil, nil
}

View file

@ -34,10 +34,11 @@ type CoordinatorClient interface {
SpaceDelete(ctx context.Context, spaceId string, conf *coordinatorproto.DeletionConfirmPayloadWithSignature) (err error)
AccountDelete(ctx context.Context, conf *coordinatorproto.DeletionConfirmPayloadWithSignature) (timestamp int64, err error)
AccountRevertDeletion(ctx context.Context) (err error)
StatusCheckMany(ctx context.Context, spaceIds []string) (statuses []*coordinatorproto.SpaceStatusPayload, err error)
StatusCheckMany(ctx context.Context, spaceIds []string) (statuses []*coordinatorproto.SpaceStatusPayload, limits *coordinatorproto.AccountLimits, err error)
StatusCheck(ctx context.Context, spaceId string) (status *coordinatorproto.SpaceStatusPayload, err error)
SpaceSign(ctx context.Context, payload SpaceSignPayload) (receipt *coordinatorproto.SpaceReceiptWithSignature, err error)
FileLimitCheck(ctx context.Context, spaceId string, identity []byte) (response *coordinatorproto.FileLimitCheckResponse, err error)
SpaceMakeShareable(ctx context.Context, spaceId string) (err error)
SpaceMakeUnshareable(ctx context.Context, spaceId, aclId string) (err error)
NetworkConfiguration(ctx context.Context, currentId string) (*coordinatorproto.NetworkConfigurationResponse, error)
DeletionLog(ctx context.Context, lastRecordId string, limit int) (records []*coordinatorproto.DeletionLogRecord, err error)
@ -47,6 +48,8 @@ type CoordinatorClient interface {
AclAddRecord(ctx context.Context, spaceId string, rec *consensusproto.RawRecord) (res *consensusproto.RawRecordWithId, err error)
AclGetRecords(ctx context.Context, spaceId, aclHead string) (res []*consensusproto.RawRecordWithId, err error)
AccountLimitsSet(ctx context.Context, req *coordinatorproto.AccountLimitsSetRequest) error
app.Component
}
@ -146,7 +149,11 @@ func (c *coordinatorClient) DeletionLog(ctx context.Context, lastRecordId string
return
}
func (c *coordinatorClient) StatusCheckMany(ctx context.Context, spaceIds []string) (statuses []*coordinatorproto.SpaceStatusPayload, err error) {
func (c *coordinatorClient) StatusCheckMany(ctx context.Context, spaceIds []string) (
statuses []*coordinatorproto.SpaceStatusPayload,
limits *coordinatorproto.AccountLimits,
err error,
) {
err = c.doClient(ctx, func(cl coordinatorproto.DRPCCoordinatorClient) error {
resp, err := cl.SpaceStatusCheckMany(ctx, &coordinatorproto.SpaceStatusCheckManyRequest{
SpaceIds: spaceIds,
@ -155,6 +162,7 @@ func (c *coordinatorClient) StatusCheckMany(ctx context.Context, spaceIds []stri
return rpcerr.Unwrap(err)
}
statuses = resp.Payloads
limits = resp.AccountLimits
return nil
})
return
@ -207,20 +215,6 @@ func (c *coordinatorClient) SpaceSign(ctx context.Context, payload SpaceSignPayl
return
}
func (c *coordinatorClient) FileLimitCheck(ctx context.Context, spaceId string, identity []byte) (resp *coordinatorproto.FileLimitCheckResponse, err error) {
err = c.doClient(ctx, func(cl coordinatorproto.DRPCCoordinatorClient) error {
resp, err = cl.FileLimitCheck(ctx, &coordinatorproto.FileLimitCheckRequest{
AccountIdentity: identity,
SpaceId: spaceId,
})
if err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
func (c *coordinatorClient) NetworkConfiguration(ctx context.Context, currentId string) (resp *coordinatorproto.NetworkConfigurationResponse, err error) {
err = c.doClient(ctx, func(cl coordinatorproto.DRPCCoordinatorClient) error {
resp, err = cl.NetworkConfiguration(ctx, &coordinatorproto.NetworkConfigurationRequest{
@ -274,7 +268,7 @@ func (c *coordinatorClient) AclAddRecord(ctx context.Context, spaceId string, re
Payload: recordData,
})
if err != nil {
return err
return rpcerr.Unwrap(err)
}
res = &consensusproto.RawRecordWithId{
Payload: resp.Payload,
@ -292,7 +286,7 @@ func (c *coordinatorClient) AclGetRecords(ctx context.Context, spaceId, aclHead
AclHead: aclHead,
})
if err != nil {
return err
return rpcerr.Unwrap(err)
}
res = make([]*consensusproto.RawRecordWithId, len(resp.Records))
for i, rec := range resp.Records {
@ -306,6 +300,38 @@ func (c *coordinatorClient) AclGetRecords(ctx context.Context, spaceId, aclHead
return
}
func (c *coordinatorClient) AccountLimitsSet(ctx context.Context, req *coordinatorproto.AccountLimitsSetRequest) error {
return c.doClient(ctx, func(cl coordinatorproto.DRPCCoordinatorClient) error {
if _, err := cl.AccountLimitsSet(ctx, req); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
}
func (c *coordinatorClient) SpaceMakeShareable(ctx context.Context, spaceId string) (err error) {
return c.doClient(ctx, func(cl coordinatorproto.DRPCCoordinatorClient) error {
if _, err := cl.SpaceMakeShareable(ctx, &coordinatorproto.SpaceMakeShareableRequest{
SpaceId: spaceId,
}); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
}
func (c *coordinatorClient) SpaceMakeUnshareable(ctx context.Context, spaceId, aclHead string) (err error) {
return c.doClient(ctx, func(cl coordinatorproto.DRPCCoordinatorClient) error {
if _, err := cl.SpaceMakeUnshareable(ctx, &coordinatorproto.SpaceMakeUnshareableRequest{
SpaceId: spaceId,
AclHead: aclHead,
}); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
}
func (c *coordinatorClient) doClient(ctx context.Context, f func(cl coordinatorproto.DRPCCoordinatorClient) error) error {
p, err := c.getPeer(ctx)
if err != nil {

View file

@ -59,6 +59,20 @@ func (mr *MockCoordinatorClientMockRecorder) AccountDelete(arg0, arg1 any) *gomo
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountDelete", reflect.TypeOf((*MockCoordinatorClient)(nil).AccountDelete), arg0, arg1)
}
// AccountLimitsSet mocks base method.
func (m *MockCoordinatorClient) AccountLimitsSet(arg0 context.Context, arg1 *coordinatorproto.AccountLimitsSetRequest) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AccountLimitsSet", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// AccountLimitsSet indicates an expected call of AccountLimitsSet.
func (mr *MockCoordinatorClientMockRecorder) AccountLimitsSet(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountLimitsSet", reflect.TypeOf((*MockCoordinatorClient)(nil).AccountLimitsSet), arg0, arg1)
}
// AccountRevertDeletion mocks base method.
func (m *MockCoordinatorClient) AccountRevertDeletion(arg0 context.Context) error {
m.ctrl.T.Helper()
@ -118,21 +132,6 @@ func (mr *MockCoordinatorClientMockRecorder) DeletionLog(arg0, arg1, arg2 any) *
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletionLog", reflect.TypeOf((*MockCoordinatorClient)(nil).DeletionLog), arg0, arg1, arg2)
}
// FileLimitCheck mocks base method.
func (m *MockCoordinatorClient) FileLimitCheck(arg0 context.Context, arg1 string, arg2 []byte) (*coordinatorproto.FileLimitCheckResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FileLimitCheck", arg0, arg1, arg2)
ret0, _ := ret[0].(*coordinatorproto.FileLimitCheckResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FileLimitCheck indicates an expected call of FileLimitCheck.
func (mr *MockCoordinatorClientMockRecorder) FileLimitCheck(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileLimitCheck", reflect.TypeOf((*MockCoordinatorClient)(nil).FileLimitCheck), arg0, arg1, arg2)
}
// IdentityRepoGet mocks base method.
func (m *MockCoordinatorClient) IdentityRepoGet(arg0 context.Context, arg1, arg2 []string) ([]*identityrepoproto.DataWithIdentity, error) {
m.ctrl.T.Helper()
@ -219,6 +218,34 @@ func (mr *MockCoordinatorClientMockRecorder) SpaceDelete(arg0, arg1, arg2 any) *
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceDelete", reflect.TypeOf((*MockCoordinatorClient)(nil).SpaceDelete), arg0, arg1, arg2)
}
// SpaceMakeShareable mocks base method.
func (m *MockCoordinatorClient) SpaceMakeShareable(arg0 context.Context, arg1 string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SpaceMakeShareable", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// SpaceMakeShareable indicates an expected call of SpaceMakeShareable.
func (mr *MockCoordinatorClientMockRecorder) SpaceMakeShareable(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceMakeShareable", reflect.TypeOf((*MockCoordinatorClient)(nil).SpaceMakeShareable), arg0, arg1)
}
// SpaceMakeUnshareable mocks base method.
func (m *MockCoordinatorClient) SpaceMakeUnshareable(arg0 context.Context, arg1, arg2 string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SpaceMakeUnshareable", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// SpaceMakeUnshareable indicates an expected call of SpaceMakeUnshareable.
func (mr *MockCoordinatorClientMockRecorder) SpaceMakeUnshareable(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceMakeUnshareable", reflect.TypeOf((*MockCoordinatorClient)(nil).SpaceMakeUnshareable), arg0, arg1, arg2)
}
// SpaceSign mocks base method.
func (m *MockCoordinatorClient) SpaceSign(arg0 context.Context, arg1 coordinatorclient.SpaceSignPayload) (*coordinatorproto.SpaceReceiptWithSignature, error) {
m.ctrl.T.Helper()
@ -250,12 +277,13 @@ func (mr *MockCoordinatorClientMockRecorder) StatusCheck(arg0, arg1 any) *gomock
}
// StatusCheckMany mocks base method.
func (m *MockCoordinatorClient) StatusCheckMany(arg0 context.Context, arg1 []string) ([]*coordinatorproto.SpaceStatusPayload, error) {
func (m *MockCoordinatorClient) StatusCheckMany(arg0 context.Context, arg1 []string) ([]*coordinatorproto.SpaceStatusPayload, *coordinatorproto.AccountLimits, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "StatusCheckMany", arg0, arg1)
ret0, _ := ret[0].([]*coordinatorproto.SpaceStatusPayload)
ret1, _ := ret[1].(error)
return ret0, ret1
ret1, _ := ret[1].(*coordinatorproto.AccountLimits)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// StatusCheckMany indicates an expected call of StatusCheckMany.

File diff suppressed because it is too large Load diff

View file

@ -41,10 +41,11 @@ type DRPCCoordinatorClient interface {
DRPCConn() drpc.Conn
SpaceSign(ctx context.Context, in *SpaceSignRequest) (*SpaceSignResponse, error)
FileLimitCheck(ctx context.Context, in *FileLimitCheckRequest) (*FileLimitCheckResponse, error)
SpaceStatusCheck(ctx context.Context, in *SpaceStatusCheckRequest) (*SpaceStatusCheckResponse, error)
SpaceStatusCheckMany(ctx context.Context, in *SpaceStatusCheckManyRequest) (*SpaceStatusCheckManyResponse, error)
SpaceStatusChange(ctx context.Context, in *SpaceStatusChangeRequest) (*SpaceStatusChangeResponse, error)
SpaceMakeShareable(ctx context.Context, in *SpaceMakeShareableRequest) (*SpaceMakeShareableResponse, error)
SpaceMakeUnshareable(ctx context.Context, in *SpaceMakeUnshareableRequest) (*SpaceMakeUnshareableResponse, error)
NetworkConfiguration(ctx context.Context, in *NetworkConfigurationRequest) (*NetworkConfigurationResponse, error)
DeletionLog(ctx context.Context, in *DeletionLogRequest) (*DeletionLogResponse, error)
SpaceDelete(ctx context.Context, in *SpaceDeleteRequest) (*SpaceDeleteResponse, error)
@ -52,6 +53,7 @@ type DRPCCoordinatorClient interface {
AccountRevertDeletion(ctx context.Context, in *AccountRevertDeletionRequest) (*AccountRevertDeletionResponse, error)
AclAddRecord(ctx context.Context, in *AclAddRecordRequest) (*AclAddRecordResponse, error)
AclGetRecords(ctx context.Context, in *AclGetRecordsRequest) (*AclGetRecordsResponse, error)
AccountLimitsSet(ctx context.Context, in *AccountLimitsSetRequest) (*AccountLimitsSetResponse, error)
}
type drpcCoordinatorClient struct {
@ -73,15 +75,6 @@ func (c *drpcCoordinatorClient) SpaceSign(ctx context.Context, in *SpaceSignRequ
return out, nil
}
func (c *drpcCoordinatorClient) FileLimitCheck(ctx context.Context, in *FileLimitCheckRequest) (*FileLimitCheckResponse, error) {
out := new(FileLimitCheckResponse)
err := c.cc.Invoke(ctx, "/coordinator.Coordinator/FileLimitCheck", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcCoordinatorClient) SpaceStatusCheck(ctx context.Context, in *SpaceStatusCheckRequest) (*SpaceStatusCheckResponse, error) {
out := new(SpaceStatusCheckResponse)
err := c.cc.Invoke(ctx, "/coordinator.Coordinator/SpaceStatusCheck", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, in, out)
@ -109,6 +102,24 @@ func (c *drpcCoordinatorClient) SpaceStatusChange(ctx context.Context, in *Space
return out, nil
}
func (c *drpcCoordinatorClient) SpaceMakeShareable(ctx context.Context, in *SpaceMakeShareableRequest) (*SpaceMakeShareableResponse, error) {
out := new(SpaceMakeShareableResponse)
err := c.cc.Invoke(ctx, "/coordinator.Coordinator/SpaceMakeShareable", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcCoordinatorClient) SpaceMakeUnshareable(ctx context.Context, in *SpaceMakeUnshareableRequest) (*SpaceMakeUnshareableResponse, error) {
out := new(SpaceMakeUnshareableResponse)
err := c.cc.Invoke(ctx, "/coordinator.Coordinator/SpaceMakeUnshareable", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcCoordinatorClient) NetworkConfiguration(ctx context.Context, in *NetworkConfigurationRequest) (*NetworkConfigurationResponse, error) {
out := new(NetworkConfigurationResponse)
err := c.cc.Invoke(ctx, "/coordinator.Coordinator/NetworkConfiguration", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, in, out)
@ -172,12 +183,22 @@ func (c *drpcCoordinatorClient) AclGetRecords(ctx context.Context, in *AclGetRec
return out, nil
}
func (c *drpcCoordinatorClient) AccountLimitsSet(ctx context.Context, in *AccountLimitsSetRequest) (*AccountLimitsSetResponse, error) {
out := new(AccountLimitsSetResponse)
err := c.cc.Invoke(ctx, "/coordinator.Coordinator/AccountLimitsSet", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
type DRPCCoordinatorServer interface {
SpaceSign(context.Context, *SpaceSignRequest) (*SpaceSignResponse, error)
FileLimitCheck(context.Context, *FileLimitCheckRequest) (*FileLimitCheckResponse, error)
SpaceStatusCheck(context.Context, *SpaceStatusCheckRequest) (*SpaceStatusCheckResponse, error)
SpaceStatusCheckMany(context.Context, *SpaceStatusCheckManyRequest) (*SpaceStatusCheckManyResponse, error)
SpaceStatusChange(context.Context, *SpaceStatusChangeRequest) (*SpaceStatusChangeResponse, error)
SpaceMakeShareable(context.Context, *SpaceMakeShareableRequest) (*SpaceMakeShareableResponse, error)
SpaceMakeUnshareable(context.Context, *SpaceMakeUnshareableRequest) (*SpaceMakeUnshareableResponse, error)
NetworkConfiguration(context.Context, *NetworkConfigurationRequest) (*NetworkConfigurationResponse, error)
DeletionLog(context.Context, *DeletionLogRequest) (*DeletionLogResponse, error)
SpaceDelete(context.Context, *SpaceDeleteRequest) (*SpaceDeleteResponse, error)
@ -185,6 +206,7 @@ type DRPCCoordinatorServer interface {
AccountRevertDeletion(context.Context, *AccountRevertDeletionRequest) (*AccountRevertDeletionResponse, error)
AclAddRecord(context.Context, *AclAddRecordRequest) (*AclAddRecordResponse, error)
AclGetRecords(context.Context, *AclGetRecordsRequest) (*AclGetRecordsResponse, error)
AccountLimitsSet(context.Context, *AccountLimitsSetRequest) (*AccountLimitsSetResponse, error)
}
type DRPCCoordinatorUnimplementedServer struct{}
@ -193,10 +215,6 @@ func (s *DRPCCoordinatorUnimplementedServer) SpaceSign(context.Context, *SpaceSi
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCCoordinatorUnimplementedServer) FileLimitCheck(context.Context, *FileLimitCheckRequest) (*FileLimitCheckResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCCoordinatorUnimplementedServer) SpaceStatusCheck(context.Context, *SpaceStatusCheckRequest) (*SpaceStatusCheckResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
@ -209,6 +227,14 @@ func (s *DRPCCoordinatorUnimplementedServer) SpaceStatusChange(context.Context,
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCCoordinatorUnimplementedServer) SpaceMakeShareable(context.Context, *SpaceMakeShareableRequest) (*SpaceMakeShareableResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCCoordinatorUnimplementedServer) SpaceMakeUnshareable(context.Context, *SpaceMakeUnshareableRequest) (*SpaceMakeUnshareableResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCCoordinatorUnimplementedServer) NetworkConfiguration(context.Context, *NetworkConfigurationRequest) (*NetworkConfigurationResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
@ -237,9 +263,13 @@ func (s *DRPCCoordinatorUnimplementedServer) AclGetRecords(context.Context, *Acl
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCCoordinatorUnimplementedServer) AccountLimitsSet(context.Context, *AccountLimitsSetRequest) (*AccountLimitsSetResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
type DRPCCoordinatorDescription struct{}
func (DRPCCoordinatorDescription) NumMethods() int { return 12 }
func (DRPCCoordinatorDescription) NumMethods() int { return 14 }
func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
switch n {
@ -253,15 +283,6 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec
)
}, DRPCCoordinatorServer.SpaceSign, true
case 1:
return "/coordinator.Coordinator/FileLimitCheck", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
FileLimitCheck(
ctx,
in1.(*FileLimitCheckRequest),
)
}, DRPCCoordinatorServer.FileLimitCheck, true
case 2:
return "/coordinator.Coordinator/SpaceStatusCheck", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
@ -270,7 +291,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec
in1.(*SpaceStatusCheckRequest),
)
}, DRPCCoordinatorServer.SpaceStatusCheck, true
case 3:
case 2:
return "/coordinator.Coordinator/SpaceStatusCheckMany", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
@ -279,7 +300,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec
in1.(*SpaceStatusCheckManyRequest),
)
}, DRPCCoordinatorServer.SpaceStatusCheckMany, true
case 4:
case 3:
return "/coordinator.Coordinator/SpaceStatusChange", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
@ -288,7 +309,25 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec
in1.(*SpaceStatusChangeRequest),
)
}, DRPCCoordinatorServer.SpaceStatusChange, true
case 4:
return "/coordinator.Coordinator/SpaceMakeShareable", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
SpaceMakeShareable(
ctx,
in1.(*SpaceMakeShareableRequest),
)
}, DRPCCoordinatorServer.SpaceMakeShareable, true
case 5:
return "/coordinator.Coordinator/SpaceMakeUnshareable", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
SpaceMakeUnshareable(
ctx,
in1.(*SpaceMakeUnshareableRequest),
)
}, DRPCCoordinatorServer.SpaceMakeUnshareable, true
case 6:
return "/coordinator.Coordinator/NetworkConfiguration", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
@ -297,7 +336,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec
in1.(*NetworkConfigurationRequest),
)
}, DRPCCoordinatorServer.NetworkConfiguration, true
case 6:
case 7:
return "/coordinator.Coordinator/DeletionLog", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
@ -306,7 +345,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec
in1.(*DeletionLogRequest),
)
}, DRPCCoordinatorServer.DeletionLog, true
case 7:
case 8:
return "/coordinator.Coordinator/SpaceDelete", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
@ -315,7 +354,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec
in1.(*SpaceDeleteRequest),
)
}, DRPCCoordinatorServer.SpaceDelete, true
case 8:
case 9:
return "/coordinator.Coordinator/AccountDelete", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
@ -324,7 +363,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec
in1.(*AccountDeleteRequest),
)
}, DRPCCoordinatorServer.AccountDelete, true
case 9:
case 10:
return "/coordinator.Coordinator/AccountRevertDeletion", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
@ -333,7 +372,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec
in1.(*AccountRevertDeletionRequest),
)
}, DRPCCoordinatorServer.AccountRevertDeletion, true
case 10:
case 11:
return "/coordinator.Coordinator/AclAddRecord", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
@ -342,7 +381,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec
in1.(*AclAddRecordRequest),
)
}, DRPCCoordinatorServer.AclAddRecord, true
case 11:
case 12:
return "/coordinator.Coordinator/AclGetRecords", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
@ -351,6 +390,15 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec
in1.(*AclGetRecordsRequest),
)
}, DRPCCoordinatorServer.AclGetRecords, true
case 13:
return "/coordinator.Coordinator/AccountLimitsSet", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCCoordinatorServer).
AccountLimitsSet(
ctx,
in1.(*AccountLimitsSetRequest),
)
}, DRPCCoordinatorServer.AccountLimitsSet, true
default:
return "", nil, nil, nil, false
}
@ -376,22 +424,6 @@ func (x *drpcCoordinator_SpaceSignStream) SendAndClose(m *SpaceSignResponse) err
return x.CloseSend()
}
type DRPCCoordinator_FileLimitCheckStream interface {
drpc.Stream
SendAndClose(*FileLimitCheckResponse) error
}
type drpcCoordinator_FileLimitCheckStream struct {
drpc.Stream
}
func (x *drpcCoordinator_FileLimitCheckStream) SendAndClose(m *FileLimitCheckResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCCoordinator_SpaceStatusCheckStream interface {
drpc.Stream
SendAndClose(*SpaceStatusCheckResponse) error
@ -440,6 +472,38 @@ func (x *drpcCoordinator_SpaceStatusChangeStream) SendAndClose(m *SpaceStatusCha
return x.CloseSend()
}
type DRPCCoordinator_SpaceMakeShareableStream interface {
drpc.Stream
SendAndClose(*SpaceMakeShareableResponse) error
}
type drpcCoordinator_SpaceMakeShareableStream struct {
drpc.Stream
}
func (x *drpcCoordinator_SpaceMakeShareableStream) SendAndClose(m *SpaceMakeShareableResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCCoordinator_SpaceMakeUnshareableStream interface {
drpc.Stream
SendAndClose(*SpaceMakeUnshareableResponse) error
}
type drpcCoordinator_SpaceMakeUnshareableStream struct {
drpc.Stream
}
func (x *drpcCoordinator_SpaceMakeUnshareableStream) SendAndClose(m *SpaceMakeUnshareableResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCCoordinator_NetworkConfigurationStream interface {
drpc.Stream
SendAndClose(*NetworkConfigurationResponse) error
@ -551,3 +615,19 @@ func (x *drpcCoordinator_AclGetRecordsStream) SendAndClose(m *AclGetRecordsRespo
}
return x.CloseSend()
}
type DRPCCoordinator_AccountLimitsSetStream interface {
drpc.Stream
SendAndClose(*AccountLimitsSetResponse) error
}
type drpcCoordinator_AccountLimitsSetStream struct {
drpc.Stream
}
func (x *drpcCoordinator_AccountLimitsSetStream) SendAndClose(m *AccountLimitsSetResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil {
return err
}
return x.CloseSend()
}

View file

@ -16,4 +16,8 @@ var (
ErrSpaceNotExists = errGroup.Register(errors.New("space not exists"), uint64(ErrorCodes_SpaceNotExists))
ErrSpaceLimitReached = errGroup.Register(errors.New("space limit reached"), uint64(ErrorCodes_SpaceLimitReached))
ErrAccountIsDeleted = errGroup.Register(errors.New("account is deleted"), uint64(ErrorCodes_AccountDeleted))
ErrForbidden = errGroup.Register(errors.New("forbidden"), uint64(ErrorCodes_Forbidden))
ErrAclHeadIsMissing = errGroup.Register(errors.New("acl head is missing"), uint64(ErrorCodes_AclHeadIsMissing))
ErrAclNonEmpty = errGroup.Register(errors.New("acl is not empty"), uint64(ErrorCodes_AclNonEmpty))
ErrSpaceNotShareable = errGroup.Register(errors.New("space not shareable"), uint64(ErrorCodes_SpaceNotShareable))
)

View file

@ -7,12 +7,6 @@ service Coordinator {
// SpaceSign signs a space creation operation
rpc SpaceSign(SpaceSignRequest) returns (SpaceSignResponse);
// FileLimitCheck checks a limit by account and space
// can be used only:
// - if a handshake identity matches a given identity
// - if a requester contains in nodeconf list
rpc FileLimitCheck(FileLimitCheckRequest) returns (FileLimitCheckResponse);
// SpaceStatusCheck checks the status of space and tells if it is deleted or not
rpc SpaceStatusCheck(SpaceStatusCheckRequest) returns (SpaceStatusCheckResponse);
@ -22,6 +16,12 @@ service Coordinator {
// SpaceStatusChange changes the status of space - Deprecated
rpc SpaceStatusChange(SpaceStatusChangeRequest) returns (SpaceStatusChangeResponse);
// SpaceMakeShareable makes space shareable
rpc SpaceMakeShareable(SpaceMakeShareableRequest) returns (SpaceMakeShareableResponse);
// SpaceMakeUnshareable marks space unshareable
rpc SpaceMakeUnshareable(SpaceMakeUnshareableRequest) returns (SpaceMakeUnshareableResponse);
// NetworkConfiguration retrieves the latest network configuration
rpc NetworkConfiguration(NetworkConfigurationRequest) returns (NetworkConfigurationResponse);
@ -41,6 +41,8 @@ service Coordinator {
rpc AclAddRecord(AclAddRecordRequest) returns (AclAddRecordResponse);
// AclGetRecords gets acl records
rpc AclGetRecords(AclGetRecordsRequest) returns (AclGetRecordsResponse);
// AccountLimitsSet sets limits to the account. Can be used only by a network config member
rpc AccountLimitsSet(AccountLimitsSetRequest) returns (AccountLimitsSetResponse);
}
message SpaceSignRequest {
@ -64,6 +66,10 @@ enum ErrorCodes {
SpaceNotExists = 4;
SpaceLimitReached = 5;
AccountDeleted = 6;
Forbidden = 7;
AclHeadIsMissing = 8;
AclNonEmpty = 9;
SpaceNotShareable = 10;
ErrorOffset = 300;
}
@ -80,10 +86,17 @@ enum SpacePermissions {
SpacePermissionsOwner = 1;
}
message SpaceLimits {
uint32 readMembers = 1;
uint32 writeMembers = 2;
}
message SpaceStatusPayload {
SpaceStatus status = 1;
int64 deletionTimestamp = 2;
SpacePermissions permissions = 3;
SpaceLimits limits = 4;
bool isShared = 5;
}
message SpaceSignResponse {
@ -110,21 +123,6 @@ message SpaceReceipt {
uint64 validUntil = 5;
}
// FileLimitCheckRequest contains an account identity and spaceId
// control node checks that identity owns a given space
message FileLimitCheckRequest {
bytes accountIdentity = 1;
string spaceId = 2;
}
// FileLimitCheckResponse returns a current space limit in bytes
message FileLimitCheckResponse {
// Limit in bytes
uint64 limit = 1;
// StorageKey tells a key that filenode should use to save files
string storageKey = 2;
}
// SpaceStatusCheckRequest contains the spaceId of requested space
message SpaceStatusCheckRequest {
string spaceId = 1;
@ -143,8 +141,15 @@ message SpaceStatusCheckManyRequest {
// SpaceStatusCheckManyResponse contains the current statuses of spaces
message SpaceStatusCheckManyResponse {
repeated SpaceStatusPayload payloads = 1;
AccountLimits accountLimits = 2;
}
// AccountLimits describes account level limit
message AccountLimits {
uint32 sharedSpacesLimit = 1;
}
// SpaceStatusChangeRequest contains the deletionChange if we want to delete space, or it is empty otherwise
message SpaceStatusChangeRequest {
string spaceId = 1;
@ -158,6 +163,19 @@ message SpaceStatusChangeResponse {
SpaceStatusPayload payload = 1;
}
message SpaceMakeShareableRequest {
string spaceId = 1;
}
message SpaceMakeShareableResponse {}
message SpaceMakeUnshareableRequest {
string spaceId = 1;
string aclHead = 2;
}
message SpaceMakeUnshareableResponse {}
// NetworkConfigurationRequest contains currenId of the client configuration, it can be empty
message NetworkConfigurationRequest {
// currenId of the client configuration
@ -335,4 +353,16 @@ message AclGetRecordsRequest {
// AclGetRecordsResponse contains list of marshaled consensusproto.RawRecordWithId
message AclGetRecordsResponse {
repeated bytes records = 1;
}
}
message AccountLimitsSetRequest {
string identity = 1;
string reason = 2;
uint64 fileStorageLimitBytes = 3;
uint32 spaceMembersRead = 4;
uint32 spaceMembersWrite = 5;
uint32 sharedSpacesLimit = 6;
}
message AccountLimitsSetResponse {}

57
go.mod
View file

@ -1,15 +1,16 @@
module github.com/anyproto/any-sync
go 1.19
go 1.22
require (
filippo.io/edwards25519 v1.1.0
github.com/anyproto/go-chash v0.1.0
github.com/anyproto/go-slip10 v1.0.0
github.com/anyproto/go-slip21 v1.0.0
github.com/btcsuite/btcd v0.22.1
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce
github.com/cespare/xxhash v1.1.0
github.com/cheggaaa/mb/v3 v3.0.2
github.com/ethereum/go-ethereum v1.13.12
github.com/gobwas/glob v0.2.3
github.com/goccy/go-graphviz v0.1.2
github.com/gogo/protobuf v1.3.2
@ -20,22 +21,22 @@ require (
github.com/ipfs/go-block-format v0.2.0
github.com/ipfs/go-cid v0.4.1
github.com/ipfs/go-ipld-format v0.6.0
github.com/libp2p/go-libp2p v0.32.2
github.com/miguelmota/go-ethereum-hdwallet v0.1.2
github.com/libp2p/go-libp2p v0.33.2
github.com/mr-tron/base58 v1.2.0
github.com/multiformats/go-multibase v0.2.0
github.com/multiformats/go-multihash v0.2.3
github.com/prometheus/client_golang v1.19.0
github.com/quic-go/quic-go v0.40.1
github.com/stretchr/testify v1.8.4
github.com/prometheus/client_golang v1.19.1
github.com/quic-go/quic-go v0.44.0
github.com/stretchr/testify v1.9.0
github.com/tyler-smith/go-bip39 v1.1.0
github.com/zeebo/blake3 v0.2.3
go.uber.org/atomic v1.11.0
go.uber.org/mock v0.4.0
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.20.0
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3
golang.org/x/net v0.21.0
golang.org/x/crypto v0.23.0
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
golang.org/x/net v0.25.0
golang.org/x/time v0.5.0
gopkg.in/yaml.v3 v3.0.1
storj.io/drpc v0.0.34
)
@ -43,28 +44,20 @@ require (
require (
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.10.0 // indirect
github.com/btcsuite/btcd v0.22.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.12.1 // indirect
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect
github.com/crate-crypto/go-kzg-4844 v0.7.0 // 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.2.0 // indirect
github.com/ethereum/c-kzg-4844 v0.4.0 // indirect
github.com/fogleman/gg v1.3.0 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/pprof v0.0.0-20240402174815-29b9bb013b0f // indirect
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
github.com/holiman/uint256 v1.2.4 // indirect
github.com/ipfs/bbloom v0.0.4 // indirect
github.com/ipfs/go-bitfield v1.1.0 // indirect
github.com/ipfs/go-datastore v0.6.0 // indirect
@ -76,38 +69,34 @@ require (
github.com/ipld/go-ipld-prime v0.21.0 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/multiformats/go-multiaddr v0.12.0 // indirect
github.com/multiformats/go-multiaddr v0.12.3 // indirect
github.com/multiformats/go-multicodec v0.9.0 // indirect
github.com/multiformats/go-multistream v0.5.0 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/onsi/ginkgo/v2 v2.15.0 // indirect
github.com/onsi/ginkgo/v2 v2.17.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/polydawn/refmt v0.89.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/client_model v0.6.0 // indirect
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/supranational/blst v0.3.11 // indirect
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect
github.com/zeebo/errs v1.3.0 // indirect
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/image v0.14.0 // indirect
golang.org/x/mod v0.15.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/tools v0.17.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/tools v0.21.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
lukechampine.com/blake3 v1.2.1 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)

181
go.sum
View file

@ -1,11 +1,8 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
@ -17,15 +14,12 @@ github.com/anyproto/go-slip21 v1.0.0 h1:CI7lUqTIwmPOEGVAj4jyNLoICvueh++0U2HoAi3m
github.com/anyproto/go-slip21 v1.0.0/go.mod h1:gbIJt7HAdr5DuT4f2pFTKCBSUWYsm/fysHBNqgsuxT0=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88=
github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
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.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k=
github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU=
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/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
@ -43,24 +37,13 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cheggaaa/mb/v3 v3.0.2 h1:jd1Xx0zzihZlXL6HmnRXVCI1BHuXz/kY+VzX9WbvNDU=
github.com/cheggaaa/mb/v3 v3.0.2/go.mod h1:zCt2QeYukhd/g0bIdNqF+b/kKz1hnLFNDkP49qN5kqI=
github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y=
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY=
github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A=
github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw=
github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M=
github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY=
github.com/corona10/goimagehash v1.0.2 h1:pUfB0LnsJASMPGEZLj7tGY251vF+qLGqOgEP4rUs6kA=
github.com/corona10/goimagehash v1.0.2/go.mod h1:/l9umBhvcHQXVtQO1V6Gp1yD20STawkhRnnX0D1bvVI=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg=
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE=
github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ=
github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA=
github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc=
github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0=
github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/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=
@ -68,25 +51,23 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
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.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY=
github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
github.com/ethereum/go-ethereum v1.13.12 h1:iDr9UM2JWkngBHGovRJEQn4Kor7mT4gt9rUZqB5M29Y=
github.com/ethereum/go-ethereum v1.13.12/go.mod h1:hKL2Qcj1OvStXNSEDbucexqnEt1Wh4Cz329XsjAalZY=
github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ=
github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
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/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
@ -94,35 +75,35 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/goccy/go-graphviz v0.1.2 h1:sWSJ6w13BCm/ZOUTHDVrdvbsxqN8yyzaFcHrH/hQ9Yg=
github.com/goccy/go-graphviz v0.1.2/go.mod h1:pMYpbAqJT10V8dzV1JN/g/wUlG/0imKPzn3ZsrchGCI=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
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/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo=
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/pprof v0.0.0-20240402174815-29b9bb013b0f h1:f00RU+zOX+B3rLAmMMkzHUF2h1z4DeYR9tTCvEq2REY=
github.com/google/pprof v0.0.0-20240402174815-29b9bb013b0f/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=
github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU=
github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c=
github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U=
github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw=
github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w=
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
github.com/ipfs/boxo v0.13.1 h1:nQ5oQzcMZR3oL41REJDcTbrvDvuZh3J9ckc9+ILeRQI=
@ -136,9 +117,13 @@ github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LK
github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk=
github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8=
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ=
github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk=
github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ=
github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE=
github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4=
github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8=
github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ=
github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U=
@ -150,11 +135,13 @@ github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOL
github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg=
github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY=
github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg=
github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU=
github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc=
github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s=
github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E=
github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
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=
@ -167,44 +154,47 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
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/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI=
github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
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-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ=
github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk=
github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s=
github.com/libp2p/go-libp2p v0.33.2 h1:vCdwnFxoGOXMKmaGHlDSnL4bM3fQeW8pgIa9DECnb40=
github.com/libp2p/go-libp2p v0.33.2/go.mod h1:zTeppLuCvUIkT118pFVzA8xzP/p2dJYOMApCkFh0Yww=
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8=
github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0=
github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk=
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg=
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk=
github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk=
github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU=
github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ=
github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ=
github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
github.com/miguelmota/go-ethereum-hdwallet v0.1.2 h1:mz9LO6V7QCRkLYb0AH17t5R8KeqCe3E+hx9YXpmZeXA=
github.com/miguelmota/go-ethereum-hdwallet v0.1.2/go.mod h1:fdNwFSoBFVBPnU0xpOd6l2ueqsPSH/Gch5kIvSvTGk8=
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
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 v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
@ -212,10 +202,12 @@ github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aG
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
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-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE=
github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8=
github.com/multiformats/go-multiaddr v0.12.3 h1:hVBXvPRcKG0w80VinQ23P5t7czWgg65BmIvQKjDydU8=
github.com/multiformats/go-multiaddr v0.12.3/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg=
@ -229,13 +221,14 @@ github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -243,24 +236,23 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4=
github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw=
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs=
github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q=
github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0=
github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek=
github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
@ -274,17 +266,13 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4=
github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s=
github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
@ -294,6 +282,7 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ=
github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs=
@ -309,6 +298,7 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
@ -324,18 +314,18 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/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.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo=
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
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.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -343,15 +333,15 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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=
@ -363,12 +353,15 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@ -376,30 +369,30 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
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-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
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-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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
storj.io/drpc v0.0.34 h1:q9zlQKfJ5A7x8NQNFk8x7eKUF78FMhmAbZLnFK+og7I=
storj.io/drpc v0.0.34/go.mod h1:Y9LZaa8esL1PW2IDMqJE7CFSNq7d5bQ3RI7mGPtmKMg=

View file

@ -40,18 +40,49 @@ func (m *MockAnyNsClientServiceBase) EXPECT() *MockAnyNsClientServiceBaseMockRec
return m.recorder
}
// Close mocks base method.
func (m *MockAnyNsClientServiceBase) Close(ctx context.Context) error {
// BatchGetNameByAddress mocks base method.
func (m *MockAnyNsClientServiceBase) BatchGetNameByAddress(ctx context.Context, in *nameserviceproto.BatchNameByAddressRequest) (*nameserviceproto.BatchNameByAddressResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Close", ctx)
ret0, _ := ret[0].(error)
return ret0
ret := m.ctrl.Call(m, "BatchGetNameByAddress", ctx, in)
ret0, _ := ret[0].(*nameserviceproto.BatchNameByAddressResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Close indicates an expected call of Close.
func (mr *MockAnyNsClientServiceBaseMockRecorder) Close(ctx any) *gomock.Call {
// BatchGetNameByAddress indicates an expected call of BatchGetNameByAddress.
func (mr *MockAnyNsClientServiceBaseMockRecorder) BatchGetNameByAddress(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockAnyNsClientServiceBase)(nil).Close), ctx)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchGetNameByAddress", reflect.TypeOf((*MockAnyNsClientServiceBase)(nil).BatchGetNameByAddress), ctx, in)
}
// BatchGetNameByAnyId mocks base method.
func (m *MockAnyNsClientServiceBase) BatchGetNameByAnyId(ctx context.Context, in *nameserviceproto.BatchNameByAnyIdRequest) (*nameserviceproto.BatchNameByAddressResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BatchGetNameByAnyId", ctx, in)
ret0, _ := ret[0].(*nameserviceproto.BatchNameByAddressResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// BatchGetNameByAnyId indicates an expected call of BatchGetNameByAnyId.
func (mr *MockAnyNsClientServiceBaseMockRecorder) BatchGetNameByAnyId(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchGetNameByAnyId", reflect.TypeOf((*MockAnyNsClientServiceBase)(nil).BatchGetNameByAnyId), ctx, in)
}
// BatchIsNameAvailable mocks base method.
func (m *MockAnyNsClientServiceBase) BatchIsNameAvailable(ctx context.Context, in *nameserviceproto.BatchNameAvailableRequest) (*nameserviceproto.BatchNameAvailableResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BatchIsNameAvailable", ctx, in)
ret0, _ := ret[0].(*nameserviceproto.BatchNameAvailableResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// BatchIsNameAvailable indicates an expected call of BatchIsNameAvailable.
func (mr *MockAnyNsClientServiceBaseMockRecorder) BatchIsNameAvailable(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchIsNameAvailable", reflect.TypeOf((*MockAnyNsClientServiceBase)(nil).BatchIsNameAvailable), ctx, in)
}
// GetNameByAddress mocks base method.
@ -69,6 +100,21 @@ func (mr *MockAnyNsClientServiceBaseMockRecorder) GetNameByAddress(ctx, in any)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNameByAddress", reflect.TypeOf((*MockAnyNsClientServiceBase)(nil).GetNameByAddress), ctx, in)
}
// GetNameByAnyId mocks base method.
func (m *MockAnyNsClientServiceBase) GetNameByAnyId(ctx context.Context, in *nameserviceproto.NameByAnyIdRequest) (*nameserviceproto.NameByAddressResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetNameByAnyId", ctx, in)
ret0, _ := ret[0].(*nameserviceproto.NameByAddressResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetNameByAnyId indicates an expected call of GetNameByAnyId.
func (mr *MockAnyNsClientServiceBaseMockRecorder) GetNameByAnyId(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNameByAnyId", reflect.TypeOf((*MockAnyNsClientServiceBase)(nil).GetNameByAnyId), ctx, in)
}
// Init mocks base method.
func (m *MockAnyNsClientServiceBase) Init(a *app.App) error {
m.ctrl.T.Helper()
@ -112,20 +158,6 @@ func (mr *MockAnyNsClientServiceBaseMockRecorder) Name() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockAnyNsClientServiceBase)(nil).Name))
}
// Run mocks base method.
func (m *MockAnyNsClientServiceBase) Run(ctx context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Run", ctx)
ret0, _ := ret[0].(error)
return ret0
}
// Run indicates an expected call of Run.
func (mr *MockAnyNsClientServiceBaseMockRecorder) Run(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockAnyNsClientServiceBase)(nil).Run), ctx)
}
// MockAnyNsClientService is a mock of AnyNsClientService interface.
type MockAnyNsClientService struct {
ctrl *gomock.Controller
@ -164,18 +196,64 @@ func (mr *MockAnyNsClientServiceMockRecorder) AdminFundUserAccount(ctx, in any)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdminFundUserAccount", reflect.TypeOf((*MockAnyNsClientService)(nil).AdminFundUserAccount), ctx, in)
}
// Close mocks base method.
func (m *MockAnyNsClientService) Close(ctx context.Context) error {
// AdminRegisterName mocks base method.
func (m *MockAnyNsClientService) AdminRegisterName(ctx context.Context, in *nameserviceproto.NameRegisterRequestSigned) (*nameserviceproto.OperationResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Close", ctx)
ret0, _ := ret[0].(error)
return ret0
ret := m.ctrl.Call(m, "AdminRegisterName", ctx, in)
ret0, _ := ret[0].(*nameserviceproto.OperationResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Close indicates an expected call of Close.
func (mr *MockAnyNsClientServiceMockRecorder) Close(ctx any) *gomock.Call {
// AdminRegisterName indicates an expected call of AdminRegisterName.
func (mr *MockAnyNsClientServiceMockRecorder) AdminRegisterName(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockAnyNsClientService)(nil).Close), ctx)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdminRegisterName", reflect.TypeOf((*MockAnyNsClientService)(nil).AdminRegisterName), ctx, in)
}
// BatchGetNameByAddress mocks base method.
func (m *MockAnyNsClientService) BatchGetNameByAddress(ctx context.Context, in *nameserviceproto.BatchNameByAddressRequest) (*nameserviceproto.BatchNameByAddressResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BatchGetNameByAddress", ctx, in)
ret0, _ := ret[0].(*nameserviceproto.BatchNameByAddressResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// BatchGetNameByAddress indicates an expected call of BatchGetNameByAddress.
func (mr *MockAnyNsClientServiceMockRecorder) BatchGetNameByAddress(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchGetNameByAddress", reflect.TypeOf((*MockAnyNsClientService)(nil).BatchGetNameByAddress), ctx, in)
}
// BatchGetNameByAnyId mocks base method.
func (m *MockAnyNsClientService) BatchGetNameByAnyId(ctx context.Context, in *nameserviceproto.BatchNameByAnyIdRequest) (*nameserviceproto.BatchNameByAddressResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BatchGetNameByAnyId", ctx, in)
ret0, _ := ret[0].(*nameserviceproto.BatchNameByAddressResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// BatchGetNameByAnyId indicates an expected call of BatchGetNameByAnyId.
func (mr *MockAnyNsClientServiceMockRecorder) BatchGetNameByAnyId(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchGetNameByAnyId", reflect.TypeOf((*MockAnyNsClientService)(nil).BatchGetNameByAnyId), ctx, in)
}
// BatchIsNameAvailable mocks base method.
func (m *MockAnyNsClientService) BatchIsNameAvailable(ctx context.Context, in *nameserviceproto.BatchNameAvailableRequest) (*nameserviceproto.BatchNameAvailableResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BatchIsNameAvailable", ctx, in)
ret0, _ := ret[0].(*nameserviceproto.BatchNameAvailableResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// BatchIsNameAvailable indicates an expected call of BatchIsNameAvailable.
func (mr *MockAnyNsClientServiceMockRecorder) BatchIsNameAvailable(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchIsNameAvailable", reflect.TypeOf((*MockAnyNsClientService)(nil).BatchIsNameAvailable), ctx, in)
}
// CreateOperation mocks base method.
@ -208,6 +286,21 @@ func (mr *MockAnyNsClientServiceMockRecorder) GetNameByAddress(ctx, in any) *gom
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNameByAddress", reflect.TypeOf((*MockAnyNsClientService)(nil).GetNameByAddress), ctx, in)
}
// GetNameByAnyId mocks base method.
func (m *MockAnyNsClientService) GetNameByAnyId(ctx context.Context, in *nameserviceproto.NameByAnyIdRequest) (*nameserviceproto.NameByAddressResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetNameByAnyId", ctx, in)
ret0, _ := ret[0].(*nameserviceproto.NameByAddressResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetNameByAnyId indicates an expected call of GetNameByAnyId.
func (mr *MockAnyNsClientServiceMockRecorder) GetNameByAnyId(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNameByAnyId", reflect.TypeOf((*MockAnyNsClientService)(nil).GetNameByAnyId), ctx, in)
}
// GetOperation mocks base method.
func (m *MockAnyNsClientService) GetOperation(ctx context.Context, in *nameserviceproto.GetOperationStatusRequest) (*nameserviceproto.OperationResponse, error) {
m.ctrl.T.Helper()
@ -280,17 +373,3 @@ func (mr *MockAnyNsClientServiceMockRecorder) Name() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockAnyNsClientService)(nil).Name))
}
// Run mocks base method.
func (m *MockAnyNsClientService) Run(ctx context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Run", ctx)
ret0, _ := ret[0].(error)
return ret0
}
// Run indicates an expected call of Run.
func (mr *MockAnyNsClientServiceMockRecorder) Run(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockAnyNsClientService)(nil).Run), ctx)
}

View file

@ -2,6 +2,7 @@ package nameserviceclient
import (
"context"
"errors"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/logger"
@ -25,6 +26,12 @@ type AnyNsClientServiceBase interface {
IsNameAvailable(ctx context.Context, in *nsp.NameAvailableRequest) (out *nsp.NameAvailableResponse, err error)
// reverse resolve
GetNameByAddress(ctx context.Context, in *nsp.NameByAddressRequest) (out *nsp.NameByAddressResponse, err error)
GetNameByAnyId(ctx context.Context, in *nsp.NameByAnyIdRequest) (out *nsp.NameByAddressResponse, err error)
BatchIsNameAvailable(ctx context.Context, in *nsp.BatchNameAvailableRequest) (out *nsp.BatchNameAvailableResponse, err error)
// reverse resolve
BatchGetNameByAddress(ctx context.Context, in *nsp.BatchNameByAddressRequest) (out *nsp.BatchNameByAddressResponse, err error)
BatchGetNameByAnyId(ctx context.Context, in *nsp.BatchNameByAnyIdRequest) (out *nsp.BatchNameByAddressResponse, err error)
app.Component
}
@ -34,6 +41,8 @@ type AnyNsClientService interface {
GetUserAccount(ctx context.Context, in *nsp.GetUserAccountRequest) (out *nsp.UserAccount, err error)
AdminFundUserAccount(ctx context.Context, in *nsp.AdminFundUserAccountRequestSigned) (out *nsp.OperationResponse, err error)
AdminRegisterName(ctx context.Context, in *nsp.NameRegisterRequestSigned) (out *nsp.OperationResponse, err error)
GetOperation(ctx context.Context, in *nsp.GetOperationStatusRequest) (out *nsp.OperationResponse, err error)
CreateOperation(ctx context.Context, in *nsp.CreateUserOperationRequestSigned) (out *nsp.OperationResponse, err error)
@ -60,9 +69,14 @@ func New() AnyNsClientService {
}
func (s *service) doClient(ctx context.Context, fn func(cl nsp.DRPCAnynsClient) error) error {
if len(s.nodeconf.NamingNodePeers()) == 0 {
log.Error("no namingNode peers configured")
return errors.New("no namingNode peers configured")
}
// it will try to connect to the Naming Node
// please enable "namingNode" type of node in the config (in the network.nodes array)
peer, err := s.pool.Get(ctx, s.nodeconf.NamingNodePeers()[0])
peer, err := s.pool.GetOneOf(ctx, s.nodeconf.NamingNodePeers())
log.Info("trying to connect to namingNode peer: ", zap.Any("peer", peer))
if err != nil {
@ -117,6 +131,47 @@ func (s *service) GetNameByAddress(ctx context.Context, in *nsp.NameByAddressReq
return
}
func (s *service) GetNameByAnyId(ctx context.Context, in *nsp.NameByAnyIdRequest) (out *nsp.NameByAddressResponse, err error) {
err = s.doClient(ctx, func(cl nsp.DRPCAnynsClient) error {
if out, err = cl.GetNameByAnyId(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
func (s *service) BatchIsNameAvailable(ctx context.Context, in *nsp.BatchNameAvailableRequest) (out *nsp.BatchNameAvailableResponse, err error) {
err = s.doClient(ctx, func(cl nsp.DRPCAnynsClient) error {
if out, err = cl.BatchIsNameAvailable(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
// reverse resolve
func (s *service) BatchGetNameByAddress(ctx context.Context, in *nsp.BatchNameByAddressRequest) (out *nsp.BatchNameByAddressResponse, err error) {
err = s.doClient(ctx, func(cl nsp.DRPCAnynsClient) error {
if out, err = cl.BatchGetNameByAddress(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
func (s *service) BatchGetNameByAnyId(ctx context.Context, in *nsp.BatchNameByAnyIdRequest) (out *nsp.BatchNameByAddressResponse, err error) {
err = s.doClient(ctx, func(cl nsp.DRPCAnynsClient) error {
if out, err = cl.BatchGetNameByAnyId(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
// AA
func (s *service) GetUserAccount(ctx context.Context, in *nsp.GetUserAccountRequest) (out *nsp.UserAccount, err error) {
err = s.doClientAA(ctx, func(cl nsp.DRPCAnynsAccountAbstractionClient) error {
@ -138,6 +193,16 @@ func (s *service) AdminFundUserAccount(ctx context.Context, in *nsp.AdminFundUse
return
}
func (s *service) AdminRegisterName(ctx context.Context, in *nsp.NameRegisterRequestSigned) (out *nsp.OperationResponse, err error) {
err = s.doClient(ctx, func(cl nsp.DRPCAnynsClient) error {
if out, err = cl.AdminNameRegisterSigned(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
func (s *service) GetOperation(ctx context.Context, in *nsp.GetOperationStatusRequest) (out *nsp.OperationResponse, err error) {
err = s.doClientAA(ctx, func(cl nsp.DRPCAnynsAccountAbstractionClient) error {
if out, err = cl.GetOperation(ctx, in); err != nil {

File diff suppressed because it is too large Load diff

View file

@ -470,7 +470,9 @@ type CreateUserOperationRequest struct {
SignedData []byte `protobuf:"bytes,2,opt,name=signedData,proto3" json:"signedData,omitempty"`
Context []byte `protobuf:"bytes,3,opt,name=context,proto3" json:"context,omitempty"`
OwnerEthAddress string `protobuf:"bytes,4,opt,name=ownerEthAddress,proto3" json:"ownerEthAddress,omitempty"`
OwnerAnyID string `protobuf:"bytes,5,opt,name=ownerAnyID,proto3" json:"ownerAnyID,omitempty"`
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
OwnerAnyID string `protobuf:"bytes,5,opt,name=ownerAnyID,proto3" json:"ownerAnyID,omitempty"`
// all operations currently are towards single name, please specify it
// we can use it for caching, etc purps.
FullName string `protobuf:"bytes,6,opt,name=fullName,proto3" json:"fullName,omitempty"`
@ -608,11 +610,17 @@ func (m *CreateUserOperationRequestSigned) GetSignature() []byte {
type NameRegisterRequest struct {
FullName string `protobuf:"bytes,1,opt,name=fullName,proto3" json:"fullName,omitempty"`
// A content hash attached to this name
// This should not be empty!
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
OwnerAnyAddress string `protobuf:"bytes,2,opt,name=ownerAnyAddress,proto3" json:"ownerAnyAddress,omitempty"`
// An Ethereum address that owns that name
OwnerEthAddress string `protobuf:"bytes,3,opt,name=ownerEthAddress,proto3" json:"ownerEthAddress,omitempty"`
// A SpaceID attached to this name
SpaceId string `protobuf:"bytes,4,opt,name=spaceId,proto3" json:"spaceId,omitempty"`
// if false -> name ownership will belong to ownerEthAddress
// if true -> name ownership will belong to SCW of ownerEthAddress (AccountAbstraction)
RegisterToSmartContractWallet bool `protobuf:"varint,4,opt,name=registerToSmartContractWallet,proto3" json:"registerToSmartContractWallet,omitempty"`
// How many months to register the name for
RegisterPeriodMonths uint32 `protobuf:"varint,5,opt,name=registerPeriodMonths,proto3" json:"registerPeriodMonths,omitempty"`
}
func (m *NameRegisterRequest) Reset() { *m = NameRegisterRequest{} }
@ -669,13 +677,157 @@ func (m *NameRegisterRequest) GetOwnerEthAddress() string {
return ""
}
func (m *NameRegisterRequest) GetSpaceId() string {
func (m *NameRegisterRequest) GetRegisterToSmartContractWallet() bool {
if m != nil {
return m.RegisterToSmartContractWallet
}
return false
}
func (m *NameRegisterRequest) GetRegisterPeriodMonths() uint32 {
if m != nil {
return m.RegisterPeriodMonths
}
return 0
}
type NameRegisterRequestSigned struct {
// NameRegisterRequest struct
Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"`
// payload signed by payload.ownerEthAddress
Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
}
func (m *NameRegisterRequestSigned) Reset() { *m = NameRegisterRequestSigned{} }
func (m *NameRegisterRequestSigned) String() string { return proto.CompactTextString(m) }
func (*NameRegisterRequestSigned) ProtoMessage() {}
func (*NameRegisterRequestSigned) Descriptor() ([]byte, []int) {
return fileDescriptor_c9d3f9b8b141e804, []int{10}
}
func (m *NameRegisterRequestSigned) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *NameRegisterRequestSigned) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_NameRegisterRequestSigned.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 *NameRegisterRequestSigned) XXX_Merge(src proto.Message) {
xxx_messageInfo_NameRegisterRequestSigned.Merge(m, src)
}
func (m *NameRegisterRequestSigned) XXX_Size() int {
return m.Size()
}
func (m *NameRegisterRequestSigned) XXX_DiscardUnknown() {
xxx_messageInfo_NameRegisterRequestSigned.DiscardUnknown(m)
}
var xxx_messageInfo_NameRegisterRequestSigned proto.InternalMessageInfo
func (m *NameRegisterRequestSigned) GetPayload() []byte {
if m != nil {
return m.Payload
}
return nil
}
func (m *NameRegisterRequestSigned) GetSignature() []byte {
if m != nil {
return m.Signature
}
return nil
}
type NameRegisterForSpaceRequest struct {
FullName string `protobuf:"bytes,1,opt,name=fullName,proto3" json:"fullName,omitempty"`
// A content hash attached to this name
// This should not be empty!
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
OwnerAnyAddress string `protobuf:"bytes,2,opt,name=ownerAnyAddress,proto3" json:"ownerAnyAddress,omitempty"`
// An Ethereum address that owns that name
OwnerEthAddress string `protobuf:"bytes,3,opt,name=ownerEthAddress,proto3" json:"ownerEthAddress,omitempty"`
// A SpaceID attached to this name
SpaceId string `protobuf:"bytes,4,opt,name=spaceId,proto3" json:"spaceId,omitempty"`
// How many months to register the name for
RegisterPeriodMonths uint32 `protobuf:"varint,5,opt,name=registerPeriodMonths,proto3" json:"registerPeriodMonths,omitempty"`
}
func (m *NameRegisterForSpaceRequest) Reset() { *m = NameRegisterForSpaceRequest{} }
func (m *NameRegisterForSpaceRequest) String() string { return proto.CompactTextString(m) }
func (*NameRegisterForSpaceRequest) ProtoMessage() {}
func (*NameRegisterForSpaceRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_c9d3f9b8b141e804, []int{11}
}
func (m *NameRegisterForSpaceRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *NameRegisterForSpaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_NameRegisterForSpaceRequest.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 *NameRegisterForSpaceRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_NameRegisterForSpaceRequest.Merge(m, src)
}
func (m *NameRegisterForSpaceRequest) XXX_Size() int {
return m.Size()
}
func (m *NameRegisterForSpaceRequest) XXX_DiscardUnknown() {
xxx_messageInfo_NameRegisterForSpaceRequest.DiscardUnknown(m)
}
var xxx_messageInfo_NameRegisterForSpaceRequest proto.InternalMessageInfo
func (m *NameRegisterForSpaceRequest) GetFullName() string {
if m != nil {
return m.FullName
}
return ""
}
func (m *NameRegisterForSpaceRequest) GetOwnerAnyAddress() string {
if m != nil {
return m.OwnerAnyAddress
}
return ""
}
func (m *NameRegisterForSpaceRequest) GetOwnerEthAddress() string {
if m != nil {
return m.OwnerEthAddress
}
return ""
}
func (m *NameRegisterForSpaceRequest) GetSpaceId() string {
if m != nil {
return m.SpaceId
}
return ""
}
func (m *NameRegisterForSpaceRequest) GetRegisterPeriodMonths() uint32 {
if m != nil {
return m.RegisterPeriodMonths
}
return 0
}
type GetOperationStatusRequest struct {
OperationId string `protobuf:"bytes,1,opt,name=operationId,proto3" json:"operationId,omitempty"`
}
@ -684,7 +836,7 @@ func (m *GetOperationStatusRequest) Reset() { *m = GetOperationStatusReq
func (m *GetOperationStatusRequest) String() string { return proto.CompactTextString(m) }
func (*GetOperationStatusRequest) ProtoMessage() {}
func (*GetOperationStatusRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_c9d3f9b8b141e804, []int{10}
return fileDescriptor_c9d3f9b8b141e804, []int{12}
}
func (m *GetOperationStatusRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -729,7 +881,7 @@ func (m *OperationResponse) Reset() { *m = OperationResponse{} }
func (m *OperationResponse) String() string { return proto.CompactTextString(m) }
func (*OperationResponse) ProtoMessage() {}
func (*OperationResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_c9d3f9b8b141e804, []int{11}
return fileDescriptor_c9d3f9b8b141e804, []int{13}
}
func (m *OperationResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -784,6 +936,8 @@ func init() {
proto.RegisterType((*CreateUserOperationRequest)(nil), "CreateUserOperationRequest")
proto.RegisterType((*CreateUserOperationRequestSigned)(nil), "CreateUserOperationRequestSigned")
proto.RegisterType((*NameRegisterRequest)(nil), "NameRegisterRequest")
proto.RegisterType((*NameRegisterRequestSigned)(nil), "NameRegisterRequestSigned")
proto.RegisterType((*NameRegisterForSpaceRequest)(nil), "NameRegisterForSpaceRequest")
proto.RegisterType((*GetOperationStatusRequest)(nil), "GetOperationStatusRequest")
proto.RegisterType((*OperationResponse)(nil), "OperationResponse")
}
@ -793,54 +947,59 @@ func init() {
}
var fileDescriptor_c9d3f9b8b141e804 = []byte{
// 747 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x5d, 0x4f, 0x13, 0x4d,
0x14, 0xee, 0xd2, 0xf2, 0xd1, 0x43, 0xdf, 0x52, 0xa6, 0xc0, 0xdb, 0xb7, 0xf0, 0xae, 0x65, 0x35,
0xa6, 0xf1, 0x62, 0x31, 0x98, 0x28, 0x37, 0x26, 0xae, 0x05, 0x2a, 0xc1, 0x00, 0x59, 0x24, 0x26,
0x10, 0x63, 0x86, 0xee, 0xa1, 0x36, 0xb6, 0x33, 0x75, 0x67, 0x2a, 0xf6, 0x5f, 0x98, 0xf8, 0x03,
0xbc, 0xf0, 0xcf, 0x78, 0xc9, 0xa5, 0xf1, 0xca, 0xc0, 0x1f, 0x31, 0x3b, 0x6c, 0x97, 0xdd, 0xb2,
0x6d, 0x51, 0x6e, 0x60, 0xcf, 0xb3, 0x67, 0xce, 0x79, 0x9e, 0xe7, 0xec, 0x9c, 0x14, 0xd6, 0x18,
0x6d, 0xa1, 0x40, 0xf7, 0x63, 0xa3, 0x86, 0x2b, 0xa1, 0xe7, 0xb6, 0xcb, 0x25, 0x5f, 0x51, 0x7f,
0x45, 0x18, 0x7f, 0x4b, 0xa9, 0xa9, 0x50, 0xe3, 0xdb, 0x18, 0x4c, 0x1f, 0x08, 0x74, 0xad, 0x5a,
0x8d, 0x77, 0x98, 0x24, 0x65, 0x98, 0xe1, 0xa7, 0x0c, 0xdd, 0x0d, 0xf9, 0xce, 0x72, 0x1c, 0x17,
0x85, 0x28, 0x68, 0x25, 0xad, 0x9c, 0xb6, 0xfb, 0x61, 0xb2, 0x09, 0xba, 0x82, 0xf6, 0x5b, 0xd4,
0x95, 0x15, 0xce, 0xa4, 0x4b, 0x6b, 0xaf, 0x69, 0xb3, 0x89, 0xb2, 0x77, 0x70, 0x4c, 0x1d, 0x1c,
0x91, 0x45, 0x5e, 0xc0, 0x9d, 0x01, 0x19, 0xeb, 0xd8, 0x6e, 0xf2, 0x2e, 0x3a, 0x85, 0x64, 0x49,
0x2b, 0x4f, 0xd9, 0xa3, 0xd2, 0xc8, 0x7d, 0xc8, 0x2a, 0x8d, 0x15, 0x4f, 0xc9, 0x4b, 0x3c, 0x91,
0x85, 0x54, 0x49, 0x2b, 0xa7, 0xec, 0x3e, 0x94, 0x3c, 0x84, 0x3c, 0x6f, 0xa3, 0x4b, 0x65, 0x83,
0xb3, 0x50, 0xf2, 0xb8, 0x4a, 0x8e, 0x7b, 0x65, 0xd4, 0x61, 0xd1, 0x72, 0x5a, 0x0d, 0xb6, 0xd9,
0x61, 0x4e, 0xc8, 0x2d, 0x1b, 0x3f, 0x74, 0x50, 0xfc, 0x89, 0x69, 0x3a, 0xc0, 0x15, 0x19, 0x65,
0x50, 0xca, 0x0e, 0x21, 0xc6, 0x11, 0x2c, 0x0f, 0x69, 0xb4, 0xdf, 0xa8, 0x33, 0x74, 0x48, 0x01,
0x26, 0xdb, 0xb4, 0xdb, 0xe4, 0xd4, 0x51, 0x6d, 0x32, 0x76, 0x2f, 0x24, 0x4b, 0x90, 0x16, 0x8d,
0x3a, 0xa3, 0xb2, 0xe3, 0xa2, 0xaa, 0x9e, 0xb1, 0xaf, 0x00, 0xe3, 0x8b, 0x06, 0xff, 0x07, 0xd5,
0xab, 0x54, 0xec, 0x06, 0x4a, 0xff, 0x4a, 0x88, 0x82, 0x2c, 0xd6, 0xdd, 0x5a, 0xf7, 0x27, 0x1d,
0x42, 0x54, 0xa5, 0xa8, 0x91, 0x6a, 0x8a, 0x29, 0xbb, 0x1f, 0x36, 0xde, 0xc0, 0xdd, 0xa1, 0xa4,
0x6e, 0x29, 0xda, 0x82, 0xf9, 0x2a, 0xca, 0xdb, 0x0c, 0xcd, 0xd8, 0x86, 0xc5, 0x2a, 0xca, 0x75,
0x2a, 0xe9, 0x0e, 0x6d, 0xa1, 0x8d, 0xf5, 0x86, 0x90, 0xe8, 0xda, 0x28, 0xda, 0x9c, 0x09, 0x24,
0x04, 0x52, 0x0e, 0x95, 0xd4, 0xa7, 0xa5, 0x9e, 0x3d, 0xb6, 0x35, 0xce, 0x24, 0x7e, 0x92, 0x3e,
0xa3, 0x5e, 0x68, 0x9c, 0x69, 0x50, 0xac, 0xb8, 0x48, 0x25, 0x7a, 0x9c, 0x02, 0xb5, 0x3d, 0x56,
0x71, 0xc5, 0x74, 0x00, 0xa1, 0x4c, 0xf0, 0x28, 0xf8, 0xf5, 0x42, 0x48, 0xb8, 0x59, 0x32, 0xd2,
0x2c, 0x4e, 0x63, 0xea, 0x26, 0xf3, 0x1c, 0xbf, 0x36, 0xcf, 0x22, 0x4c, 0x9d, 0x74, 0x9a, 0x4d,
0xcf, 0x80, 0xc2, 0x84, 0x7a, 0x1b, 0xc4, 0xc6, 0x21, 0x94, 0x06, 0x2b, 0xba, 0xe5, 0xf8, 0xbe,
0x6a, 0x90, 0x8f, 0xba, 0x7e, 0xe9, 0x53, 0x98, 0x8f, 0x16, 0xe5, 0x13, 0xa8, 0xb6, 0x58, 0x37,
0xba, 0x8a, 0xfa, 0xe1, 0x38, 0x7f, 0x92, 0xf1, 0xfe, 0x14, 0x60, 0x52, 0xb4, 0x69, 0x0d, 0xb7,
0x1c, 0xdf, 0xc1, 0x5e, 0x68, 0x3c, 0x85, 0xff, 0xaa, 0x28, 0x03, 0xd9, 0xfb, 0x92, 0xca, 0x4e,
0x70, 0xa1, 0x4a, 0x30, 0x1d, 0x7c, 0xef, 0x5b, 0x8e, 0xcf, 0x34, 0x0c, 0x19, 0x0c, 0x66, 0x43,
0x96, 0xf9, 0x9f, 0xd4, 0xc8, 0x63, 0xe4, 0x09, 0x64, 0x79, 0xb8, 0xe5, 0xa5, 0x75, 0xd9, 0xd5,
0x19, 0x33, 0xc2, 0x04, 0xed, 0xbe, 0xb4, 0x07, 0x47, 0x90, 0x8d, 0x66, 0x90, 0x69, 0x98, 0x3c,
0x60, 0xef, 0x19, 0x3f, 0x65, 0xb9, 0x84, 0x17, 0xec, 0x21, 0x73, 0x1a, 0xac, 0x9e, 0xd3, 0xc8,
0x3c, 0xcc, 0xfa, 0xc1, 0xae, 0xbb, 0xc3, 0xe5, 0x26, 0xef, 0x30, 0x27, 0x37, 0x46, 0xfe, 0x81,
0x74, 0x85, 0xb7, 0xda, 0x4d, 0x94, 0xe8, 0xe4, 0x92, 0x24, 0x0d, 0xe3, 0x1b, 0xae, 0xcb, 0xdd,
0x5c, 0x6a, 0xf5, 0x67, 0x12, 0xfe, 0xb5, 0x58, 0x97, 0x09, 0xff, 0xae, 0x59, 0xc7, 0xc2, 0xdb,
0xd3, 0x5e, 0x2f, 0xf2, 0x0c, 0x32, 0x61, 0x9f, 0x48, 0xd1, 0x1c, 0x68, 0x5b, 0x91, 0x98, 0xd7,
0x3c, 0x31, 0x12, 0x64, 0x0f, 0xe6, 0xe2, 0x96, 0x23, 0x31, 0xcc, 0x91, 0x3b, 0x73, 0x40, 0xc5,
0x57, 0xb0, 0x10, 0xbf, 0x7b, 0xc8, 0x3d, 0xf3, 0x06, 0x4b, 0x69, 0x40, 0xd5, 0x35, 0xc8, 0x46,
0x57, 0x0e, 0x59, 0x30, 0x63, 0x77, 0x50, 0x31, 0x63, 0x86, 0x40, 0x23, 0x41, 0xb6, 0x21, 0x1f,
0xb3, 0x69, 0xc8, 0x9c, 0x19, 0x73, 0x05, 0x8a, 0x4b, 0xe6, 0x90, 0xad, 0x64, 0x24, 0xc8, 0x0e,
0xe4, 0x63, 0xae, 0x25, 0x59, 0x36, 0x47, 0x5d, 0xd6, 0x78, 0x59, 0xcf, 0x1f, 0x7f, 0x3f, 0xd7,
0xb5, 0xb3, 0x73, 0x5d, 0xfb, 0x75, 0xae, 0x6b, 0x9f, 0x2f, 0xf4, 0xc4, 0xd9, 0x85, 0x9e, 0xf8,
0x71, 0xa1, 0x27, 0x0e, 0x97, 0x86, 0xfd, 0xfc, 0x38, 0x9e, 0x50, 0xff, 0x1e, 0xfd, 0x0e, 0x00,
0x00, 0xff, 0xff, 0xb6, 0xa8, 0xb9, 0x6c, 0xa5, 0x08, 0x00, 0x00,
// 831 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0x51, 0x6f, 0x1b, 0x45,
0x10, 0xf6, 0xc5, 0x97, 0x26, 0x9e, 0xb8, 0xae, 0xbb, 0x4e, 0x8b, 0xeb, 0xb8, 0x87, 0x7b, 0x20,
0x64, 0xf1, 0x70, 0x45, 0x41, 0x82, 0xbe, 0x20, 0x71, 0xd8, 0xb5, 0x89, 0x0a, 0x69, 0x74, 0x6e,
0x85, 0xd4, 0x08, 0xa1, 0xad, 0x6f, 0xea, 0x9e, 0xb0, 0x77, 0xcd, 0xee, 0x9a, 0xe2, 0x7f, 0x81,
0xc4, 0x4f, 0xe0, 0x47, 0xf0, 0x17, 0x78, 0xcc, 0x23, 0x12, 0x2f, 0x28, 0xf9, 0x21, 0x20, 0x6f,
0xce, 0xd7, 0x3d, 0xf7, 0x6c, 0x97, 0xf8, 0xa1, 0x2f, 0xc9, 0xcd, 0x77, 0x73, 0x33, 0xdf, 0x7c,
0xb3, 0x3b, 0x63, 0x78, 0xc0, 0xe8, 0x08, 0x25, 0x8a, 0x9f, 0xa3, 0x3e, 0xde, 0x37, 0x9e, 0xc7,
0x82, 0x2b, 0x7e, 0x5f, 0xff, 0x95, 0x26, 0xfe, 0x03, 0xa5, 0x9e, 0x46, 0xdd, 0xdf, 0xb7, 0x60,
0xef, 0xa9, 0x44, 0xe1, 0xf7, 0xfb, 0x7c, 0xc2, 0x14, 0x69, 0xc2, 0x0d, 0xfe, 0x8a, 0xa1, 0x78,
0xa8, 0x5e, 0xfa, 0x61, 0x28, 0x50, 0xca, 0xaa, 0xd5, 0xb0, 0x9a, 0x85, 0x60, 0x11, 0x26, 0x1d,
0x70, 0x34, 0xd4, 0x1b, 0x51, 0xa1, 0x5a, 0x9c, 0x29, 0x41, 0xfb, 0xdf, 0xd1, 0xe1, 0x10, 0xd5,
0xfc, 0xc3, 0x2d, 0xfd, 0xe1, 0x1a, 0x2f, 0xf2, 0x35, 0xbc, 0xbf, 0xc4, 0xa3, 0x8d, 0xe3, 0x21,
0x9f, 0x62, 0x58, 0xcd, 0x37, 0xac, 0xe6, 0x6e, 0xb0, 0xce, 0x8d, 0x7c, 0x04, 0x25, 0x5d, 0x63,
0x6b, 0x56, 0xc9, 0x37, 0xf8, 0x42, 0x55, 0xed, 0x86, 0xd5, 0xb4, 0x83, 0x05, 0x94, 0x7c, 0x02,
0x15, 0x3e, 0x46, 0x41, 0x55, 0xc4, 0x99, 0xe1, 0xbc, 0xad, 0x9d, 0xb3, 0x5e, 0xb9, 0x03, 0x38,
0xf0, 0xc3, 0x51, 0xc4, 0x3a, 0x13, 0x16, 0x1a, 0x6a, 0x05, 0xf8, 0xd3, 0x04, 0xe5, 0xff, 0x11,
0xcd, 0x01, 0x78, 0x4d, 0x46, 0x0b, 0x64, 0x07, 0x06, 0xe2, 0x9e, 0xc2, 0xbd, 0x15, 0x89, 0x7a,
0xd1, 0x80, 0x61, 0x48, 0xaa, 0xb0, 0x33, 0xa6, 0xd3, 0x21, 0xa7, 0xa1, 0x4e, 0x53, 0x0c, 0xe6,
0x26, 0xa9, 0x43, 0x41, 0x46, 0x03, 0x46, 0xd5, 0x44, 0xa0, 0x8e, 0x5e, 0x0c, 0x5e, 0x03, 0xee,
0x6f, 0x16, 0xdc, 0x4d, 0xa2, 0x77, 0xa9, 0x7c, 0x9c, 0x54, 0x7a, 0xa5, 0x42, 0x34, 0xe4, 0xb3,
0xe9, 0x51, 0x3b, 0xee, 0xb4, 0x81, 0xe8, 0x48, 0x69, 0x21, 0x75, 0x17, 0xed, 0x60, 0x11, 0x76,
0xbf, 0x87, 0x0f, 0x56, 0x92, 0xda, 0xb0, 0x68, 0x1f, 0x6e, 0x75, 0x51, 0x6d, 0xd2, 0x34, 0xf7,
0x11, 0x1c, 0x74, 0x51, 0xb5, 0xa9, 0xa2, 0xc7, 0x74, 0x84, 0x01, 0x0e, 0x22, 0xa9, 0x50, 0x04,
0x28, 0xc7, 0x9c, 0x49, 0x24, 0x04, 0xec, 0x90, 0x2a, 0x1a, 0xd3, 0xd2, 0xcf, 0x33, 0xb6, 0x7d,
0xce, 0x14, 0xfe, 0xa2, 0x62, 0x46, 0x73, 0xd3, 0x3d, 0xb3, 0xa0, 0xd6, 0x12, 0x48, 0x15, 0xce,
0x38, 0x25, 0xd5, 0xce, 0x59, 0x65, 0x05, 0x73, 0x00, 0xa4, 0x16, 0x61, 0x46, 0x21, 0x8e, 0x67,
0x20, 0x66, 0xb2, 0x7c, 0x2a, 0x59, 0x56, 0x8d, 0xf6, 0xdb, 0xf4, 0x73, 0xfb, 0x8d, 0x7e, 0xd6,
0x60, 0xf7, 0xc5, 0x64, 0x38, 0x9c, 0x09, 0x50, 0xbd, 0xa6, 0xdf, 0x26, 0xb6, 0xfb, 0x0c, 0x1a,
0xcb, 0x2b, 0xda, 0xb0, 0x7d, 0xff, 0x5a, 0x50, 0x49, 0xab, 0x7e, 0xa9, 0x93, 0xc9, 0xc7, 0x4a,
0xf3, 0x49, 0xaa, 0xf6, 0xd9, 0x34, 0x3d, 0x8a, 0x16, 0xe1, 0x2c, 0x7d, 0xf2, 0xd9, 0xfa, 0xb4,
0xe1, 0xae, 0x88, 0x29, 0x3c, 0xe1, 0xe6, 0x0c, 0x52, 0x97, 0x43, 0x48, 0xeb, 0xba, 0x1b, 0xac,
0x76, 0x22, 0x87, 0xb0, 0x3f, 0x77, 0x38, 0x41, 0x11, 0xf1, 0xf0, 0x5b, 0xce, 0xd4, 0x4b, 0xa9,
0xf5, 0xbe, 0x1e, 0x64, 0xbe, 0x73, 0x7b, 0x70, 0x27, 0x43, 0x80, 0x0d, 0x65, 0xfd, 0xdb, 0x82,
0x03, 0x33, 0x6a, 0x87, 0x8b, 0xde, 0x98, 0xf6, 0xf1, 0x5d, 0xc9, 0x5b, 0x85, 0x1d, 0x39, 0xcb,
0x7f, 0x14, 0xc6, 0x07, 0x74, 0x6e, 0x5e, 0x49, 0xb2, 0x2f, 0xe0, 0x4e, 0x17, 0x55, 0x72, 0x12,
0x7b, 0x8a, 0xaa, 0x49, 0x32, 0xe3, 0x1a, 0xb0, 0x97, 0x8c, 0xa0, 0xa3, 0x30, 0xae, 0xce, 0x84,
0x5c, 0x06, 0x37, 0x8d, 0x53, 0x1c, 0xdf, 0xf2, 0xb5, 0x9f, 0x91, 0xcf, 0xa1, 0xc4, 0xcd, 0x94,
0x97, 0xb2, 0x97, 0x0e, 0x6f, 0x78, 0x29, 0x26, 0x18, 0x2c, 0xb8, 0x7d, 0x7c, 0x0a, 0xa5, 0xb4,
0x07, 0xd9, 0x83, 0x9d, 0xa7, 0xec, 0x47, 0xc6, 0x5f, 0xb1, 0x72, 0x6e, 0x66, 0x9c, 0x20, 0x0b,
0x23, 0x36, 0x28, 0x5b, 0xe4, 0x16, 0xdc, 0x8c, 0x8d, 0xc7, 0xe2, 0x98, 0xab, 0x0e, 0x9f, 0xb0,
0xb0, 0xbc, 0x45, 0xae, 0x43, 0xa1, 0xc5, 0x47, 0xe3, 0x21, 0x2a, 0x0c, 0xcb, 0x79, 0x52, 0x80,
0xed, 0x87, 0x42, 0x70, 0x51, 0xb6, 0x0f, 0xff, 0xb0, 0xe1, 0x3d, 0x9f, 0x4d, 0x99, 0x8c, 0xc7,
0x9f, 0xff, 0x5c, 0xea, 0x13, 0x19, 0x71, 0x46, 0xbe, 0x84, 0xa2, 0xa9, 0x13, 0xa9, 0x79, 0x4b,
0x65, 0xab, 0x11, 0xef, 0x0d, 0x4d, 0xdc, 0x1c, 0x39, 0x81, 0xfd, 0xac, 0x7d, 0x45, 0x5c, 0x6f,
0xed, 0x1a, 0x5b, 0x12, 0xf1, 0x09, 0xdc, 0xce, 0x5e, 0x07, 0xe4, 0x43, 0xef, 0x2d, 0xf6, 0xc4,
0x92, 0xa8, 0x0f, 0xa0, 0x94, 0xde, 0x02, 0xe4, 0xb6, 0x97, 0xb9, 0x16, 0x6a, 0x45, 0xcf, 0x00,
0xdd, 0x1c, 0x79, 0x04, 0x95, 0x8c, 0xe1, 0x4f, 0xf6, 0xbd, 0x8c, 0x4b, 0x59, 0xab, 0x7b, 0x2b,
0x16, 0x85, 0x9b, 0x23, 0xa7, 0x99, 0x9b, 0x64, 0x7e, 0xf9, 0x48, 0xdd, 0x5b, 0x71, 0x27, 0xd7,
0x06, 0x3f, 0x86, 0x4a, 0xc6, 0x18, 0x26, 0xf7, 0xbc, 0x75, 0xc3, 0x39, 0x5b, 0xb3, 0xaf, 0x3e,
0xfb, 0xf3, 0xdc, 0xb1, 0xce, 0xce, 0x1d, 0xeb, 0x9f, 0x73, 0xc7, 0xfa, 0xf5, 0xc2, 0xc9, 0x9d,
0x5d, 0x38, 0xb9, 0xbf, 0x2e, 0x9c, 0xdc, 0xb3, 0xfa, 0xaa, 0x9f, 0x9b, 0xcf, 0xaf, 0xe9, 0x7f,
0x9f, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0xe2, 0x3c, 0xfb, 0x3d, 0x95, 0x0a, 0x00, 0x00,
}
func (m *UserAccount) Marshal() (dAtA []byte, err error) {
@ -1240,6 +1399,107 @@ func (m *NameRegisterRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.RegisterPeriodMonths != 0 {
i = encodeVarintNameserviceAa(dAtA, i, uint64(m.RegisterPeriodMonths))
i--
dAtA[i] = 0x28
}
if m.RegisterToSmartContractWallet {
i--
if m.RegisterToSmartContractWallet {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x20
}
if len(m.OwnerEthAddress) > 0 {
i -= len(m.OwnerEthAddress)
copy(dAtA[i:], m.OwnerEthAddress)
i = encodeVarintNameserviceAa(dAtA, i, uint64(len(m.OwnerEthAddress)))
i--
dAtA[i] = 0x1a
}
if len(m.OwnerAnyAddress) > 0 {
i -= len(m.OwnerAnyAddress)
copy(dAtA[i:], m.OwnerAnyAddress)
i = encodeVarintNameserviceAa(dAtA, i, uint64(len(m.OwnerAnyAddress)))
i--
dAtA[i] = 0x12
}
if len(m.FullName) > 0 {
i -= len(m.FullName)
copy(dAtA[i:], m.FullName)
i = encodeVarintNameserviceAa(dAtA, i, uint64(len(m.FullName)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *NameRegisterRequestSigned) 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 *NameRegisterRequestSigned) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *NameRegisterRequestSigned) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Signature) > 0 {
i -= len(m.Signature)
copy(dAtA[i:], m.Signature)
i = encodeVarintNameserviceAa(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 = encodeVarintNameserviceAa(dAtA, i, uint64(len(m.Payload)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *NameRegisterForSpaceRequest) 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 *NameRegisterForSpaceRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *NameRegisterForSpaceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.RegisterPeriodMonths != 0 {
i = encodeVarintNameserviceAa(dAtA, i, uint64(m.RegisterPeriodMonths))
i--
dAtA[i] = 0x28
}
if len(m.SpaceId) > 0 {
i -= len(m.SpaceId)
copy(dAtA[i:], m.SpaceId)
@ -1524,6 +1784,50 @@ func (m *CreateUserOperationRequestSigned) Size() (n int) {
}
func (m *NameRegisterRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.FullName)
if l > 0 {
n += 1 + l + sovNameserviceAa(uint64(l))
}
l = len(m.OwnerAnyAddress)
if l > 0 {
n += 1 + l + sovNameserviceAa(uint64(l))
}
l = len(m.OwnerEthAddress)
if l > 0 {
n += 1 + l + sovNameserviceAa(uint64(l))
}
if m.RegisterToSmartContractWallet {
n += 2
}
if m.RegisterPeriodMonths != 0 {
n += 1 + sovNameserviceAa(uint64(m.RegisterPeriodMonths))
}
return n
}
func (m *NameRegisterRequestSigned) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Payload)
if l > 0 {
n += 1 + l + sovNameserviceAa(uint64(l))
}
l = len(m.Signature)
if l > 0 {
n += 1 + l + sovNameserviceAa(uint64(l))
}
return n
}
func (m *NameRegisterForSpaceRequest) Size() (n int) {
if m == nil {
return 0
}
@ -1545,6 +1849,9 @@ func (m *NameRegisterRequest) Size() (n int) {
if l > 0 {
n += 1 + l + sovNameserviceAa(uint64(l))
}
if m.RegisterPeriodMonths != 0 {
n += 1 + sovNameserviceAa(uint64(m.RegisterPeriodMonths))
}
return n
}
@ -2820,6 +3127,309 @@ func (m *NameRegisterRequest) Unmarshal(dAtA []byte) error {
return fmt.Errorf("proto: NameRegisterRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field FullName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowNameserviceAa
}
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 ErrInvalidLengthNameserviceAa
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthNameserviceAa
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.FullName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field OwnerAnyAddress", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowNameserviceAa
}
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 ErrInvalidLengthNameserviceAa
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthNameserviceAa
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.OwnerAnyAddress = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field OwnerEthAddress", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowNameserviceAa
}
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 ErrInvalidLengthNameserviceAa
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthNameserviceAa
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.OwnerEthAddress = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field RegisterToSmartContractWallet", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowNameserviceAa
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.RegisterToSmartContractWallet = bool(v != 0)
case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field RegisterPeriodMonths", wireType)
}
m.RegisterPeriodMonths = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowNameserviceAa
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.RegisterPeriodMonths |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipNameserviceAa(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthNameserviceAa
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *NameRegisterRequestSigned) 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 ErrIntOverflowNameserviceAa
}
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: NameRegisterRequestSigned: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: NameRegisterRequestSigned: 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 ErrIntOverflowNameserviceAa
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthNameserviceAa
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthNameserviceAa
}
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 ErrIntOverflowNameserviceAa
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthNameserviceAa
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthNameserviceAa
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...)
if m.Signature == nil {
m.Signature = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipNameserviceAa(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthNameserviceAa
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *NameRegisterForSpaceRequest) 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 ErrIntOverflowNameserviceAa
}
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: NameRegisterForSpaceRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: NameRegisterForSpaceRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field FullName", wireType)
@ -2948,6 +3558,25 @@ func (m *NameRegisterRequest) Unmarshal(dAtA []byte) error {
}
m.SpaceId = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field RegisterPeriodMonths", wireType)
}
m.RegisterPeriodMonths = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowNameserviceAa
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.RegisterPeriodMonths |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipNameserviceAa(dAtA[iNdEx:])

View file

@ -45,6 +45,7 @@ type DRPCAnynsAccountAbstractionClient interface {
AdminFundGasOperations(ctx context.Context, in *AdminFundGasOperationsRequestSigned) (*OperationResponse, error)
GetUserAccount(ctx context.Context, in *GetUserAccountRequest) (*UserAccount, error)
GetDataNameRegister(ctx context.Context, in *NameRegisterRequest) (*GetDataNameRegisterResponse, error)
GetDataNameRegisterForSpace(ctx context.Context, in *NameRegisterForSpaceRequest) (*GetDataNameRegisterResponse, error)
CreateUserOperation(ctx context.Context, in *CreateUserOperationRequestSigned) (*OperationResponse, error)
}
@ -103,6 +104,15 @@ func (c *drpcAnynsAccountAbstractionClient) GetDataNameRegister(ctx context.Cont
return out, nil
}
func (c *drpcAnynsAccountAbstractionClient) GetDataNameRegisterForSpace(ctx context.Context, in *NameRegisterForSpaceRequest) (*GetDataNameRegisterResponse, error) {
out := new(GetDataNameRegisterResponse)
err := c.cc.Invoke(ctx, "/AnynsAccountAbstraction/GetDataNameRegisterForSpace", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_aa_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcAnynsAccountAbstractionClient) CreateUserOperation(ctx context.Context, in *CreateUserOperationRequestSigned) (*OperationResponse, error) {
out := new(OperationResponse)
err := c.cc.Invoke(ctx, "/AnynsAccountAbstraction/CreateUserOperation", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_aa_proto{}, in, out)
@ -118,6 +128,7 @@ type DRPCAnynsAccountAbstractionServer interface {
AdminFundGasOperations(context.Context, *AdminFundGasOperationsRequestSigned) (*OperationResponse, error)
GetUserAccount(context.Context, *GetUserAccountRequest) (*UserAccount, error)
GetDataNameRegister(context.Context, *NameRegisterRequest) (*GetDataNameRegisterResponse, error)
GetDataNameRegisterForSpace(context.Context, *NameRegisterForSpaceRequest) (*GetDataNameRegisterResponse, error)
CreateUserOperation(context.Context, *CreateUserOperationRequestSigned) (*OperationResponse, error)
}
@ -143,13 +154,17 @@ func (s *DRPCAnynsAccountAbstractionUnimplementedServer) GetDataNameRegister(con
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnynsAccountAbstractionUnimplementedServer) GetDataNameRegisterForSpace(context.Context, *NameRegisterForSpaceRequest) (*GetDataNameRegisterResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnynsAccountAbstractionUnimplementedServer) CreateUserOperation(context.Context, *CreateUserOperationRequestSigned) (*OperationResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
type DRPCAnynsAccountAbstractionDescription struct{}
func (DRPCAnynsAccountAbstractionDescription) NumMethods() int { return 6 }
func (DRPCAnynsAccountAbstractionDescription) NumMethods() int { return 7 }
func (DRPCAnynsAccountAbstractionDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
switch n {
@ -199,6 +214,15 @@ func (DRPCAnynsAccountAbstractionDescription) Method(n int) (string, drpc.Encodi
)
}, DRPCAnynsAccountAbstractionServer.GetDataNameRegister, true
case 5:
return "/AnynsAccountAbstraction/GetDataNameRegisterForSpace", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_aa_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnynsAccountAbstractionServer).
GetDataNameRegisterForSpace(
ctx,
in1.(*NameRegisterForSpaceRequest),
)
}, DRPCAnynsAccountAbstractionServer.GetDataNameRegisterForSpace, true
case 6:
return "/AnynsAccountAbstraction/CreateUserOperation", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_aa_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnynsAccountAbstractionServer).
@ -296,6 +320,22 @@ func (x *drpcAnynsAccountAbstraction_GetDataNameRegisterStream) SendAndClose(m *
return x.CloseSend()
}
type DRPCAnynsAccountAbstraction_GetDataNameRegisterForSpaceStream interface {
drpc.Stream
SendAndClose(*GetDataNameRegisterResponse) error
}
type drpcAnynsAccountAbstraction_GetDataNameRegisterForSpaceStream struct {
drpc.Stream
}
func (x *drpcAnynsAccountAbstraction_GetDataNameRegisterForSpaceStream) SendAndClose(m *GetDataNameRegisterResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_aa_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCAnynsAccountAbstraction_CreateUserOperationStream interface {
drpc.Stream
SendAndClose(*OperationResponse) error

View file

@ -41,7 +41,12 @@ type DRPCAnynsClient interface {
DRPCConn() drpc.Conn
IsNameAvailable(ctx context.Context, in *NameAvailableRequest) (*NameAvailableResponse, error)
BatchIsNameAvailable(ctx context.Context, in *BatchNameAvailableRequest) (*BatchNameAvailableResponse, error)
GetNameByAddress(ctx context.Context, in *NameByAddressRequest) (*NameByAddressResponse, error)
BatchGetNameByAddress(ctx context.Context, in *BatchNameByAddressRequest) (*BatchNameByAddressResponse, error)
GetNameByAnyId(ctx context.Context, in *NameByAnyIdRequest) (*NameByAddressResponse, error)
BatchGetNameByAnyId(ctx context.Context, in *BatchNameByAnyIdRequest) (*BatchNameByAddressResponse, error)
AdminNameRegisterSigned(ctx context.Context, in *NameRegisterRequestSigned) (*OperationResponse, error)
}
type drpcAnynsClient struct {
@ -63,6 +68,15 @@ func (c *drpcAnynsClient) IsNameAvailable(ctx context.Context, in *NameAvailable
return out, nil
}
func (c *drpcAnynsClient) BatchIsNameAvailable(ctx context.Context, in *BatchNameAvailableRequest) (*BatchNameAvailableResponse, error) {
out := new(BatchNameAvailableResponse)
err := c.cc.Invoke(ctx, "/Anyns/BatchIsNameAvailable", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcAnynsClient) GetNameByAddress(ctx context.Context, in *NameByAddressRequest) (*NameByAddressResponse, error) {
out := new(NameByAddressResponse)
err := c.cc.Invoke(ctx, "/Anyns/GetNameByAddress", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{}, in, out)
@ -72,9 +86,50 @@ func (c *drpcAnynsClient) GetNameByAddress(ctx context.Context, in *NameByAddres
return out, nil
}
func (c *drpcAnynsClient) BatchGetNameByAddress(ctx context.Context, in *BatchNameByAddressRequest) (*BatchNameByAddressResponse, error) {
out := new(BatchNameByAddressResponse)
err := c.cc.Invoke(ctx, "/Anyns/BatchGetNameByAddress", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcAnynsClient) GetNameByAnyId(ctx context.Context, in *NameByAnyIdRequest) (*NameByAddressResponse, error) {
out := new(NameByAddressResponse)
err := c.cc.Invoke(ctx, "/Anyns/GetNameByAnyId", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcAnynsClient) BatchGetNameByAnyId(ctx context.Context, in *BatchNameByAnyIdRequest) (*BatchNameByAddressResponse, error) {
out := new(BatchNameByAddressResponse)
err := c.cc.Invoke(ctx, "/Anyns/BatchGetNameByAnyId", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcAnynsClient) AdminNameRegisterSigned(ctx context.Context, in *NameRegisterRequestSigned) (*OperationResponse, error) {
out := new(OperationResponse)
err := c.cc.Invoke(ctx, "/Anyns/AdminNameRegisterSigned", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
type DRPCAnynsServer interface {
IsNameAvailable(context.Context, *NameAvailableRequest) (*NameAvailableResponse, error)
BatchIsNameAvailable(context.Context, *BatchNameAvailableRequest) (*BatchNameAvailableResponse, error)
GetNameByAddress(context.Context, *NameByAddressRequest) (*NameByAddressResponse, error)
BatchGetNameByAddress(context.Context, *BatchNameByAddressRequest) (*BatchNameByAddressResponse, error)
GetNameByAnyId(context.Context, *NameByAnyIdRequest) (*NameByAddressResponse, error)
BatchGetNameByAnyId(context.Context, *BatchNameByAnyIdRequest) (*BatchNameByAddressResponse, error)
AdminNameRegisterSigned(context.Context, *NameRegisterRequestSigned) (*OperationResponse, error)
}
type DRPCAnynsUnimplementedServer struct{}
@ -83,13 +138,33 @@ func (s *DRPCAnynsUnimplementedServer) IsNameAvailable(context.Context, *NameAva
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnynsUnimplementedServer) BatchIsNameAvailable(context.Context, *BatchNameAvailableRequest) (*BatchNameAvailableResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnynsUnimplementedServer) GetNameByAddress(context.Context, *NameByAddressRequest) (*NameByAddressResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnynsUnimplementedServer) BatchGetNameByAddress(context.Context, *BatchNameByAddressRequest) (*BatchNameByAddressResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnynsUnimplementedServer) GetNameByAnyId(context.Context, *NameByAnyIdRequest) (*NameByAddressResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnynsUnimplementedServer) BatchGetNameByAnyId(context.Context, *BatchNameByAnyIdRequest) (*BatchNameByAddressResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnynsUnimplementedServer) AdminNameRegisterSigned(context.Context, *NameRegisterRequestSigned) (*OperationResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
type DRPCAnynsDescription struct{}
func (DRPCAnynsDescription) NumMethods() int { return 2 }
func (DRPCAnynsDescription) NumMethods() int { return 7 }
func (DRPCAnynsDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
switch n {
@ -103,6 +178,15 @@ func (DRPCAnynsDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver,
)
}, DRPCAnynsServer.IsNameAvailable, true
case 1:
return "/Anyns/BatchIsNameAvailable", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnynsServer).
BatchIsNameAvailable(
ctx,
in1.(*BatchNameAvailableRequest),
)
}, DRPCAnynsServer.BatchIsNameAvailable, true
case 2:
return "/Anyns/GetNameByAddress", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnynsServer).
@ -111,6 +195,42 @@ func (DRPCAnynsDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver,
in1.(*NameByAddressRequest),
)
}, DRPCAnynsServer.GetNameByAddress, true
case 3:
return "/Anyns/BatchGetNameByAddress", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnynsServer).
BatchGetNameByAddress(
ctx,
in1.(*BatchNameByAddressRequest),
)
}, DRPCAnynsServer.BatchGetNameByAddress, true
case 4:
return "/Anyns/GetNameByAnyId", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnynsServer).
GetNameByAnyId(
ctx,
in1.(*NameByAnyIdRequest),
)
}, DRPCAnynsServer.GetNameByAnyId, true
case 5:
return "/Anyns/BatchGetNameByAnyId", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnynsServer).
BatchGetNameByAnyId(
ctx,
in1.(*BatchNameByAnyIdRequest),
)
}, DRPCAnynsServer.BatchGetNameByAnyId, true
case 6:
return "/Anyns/AdminNameRegisterSigned", drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnynsServer).
AdminNameRegisterSigned(
ctx,
in1.(*NameRegisterRequestSigned),
)
}, DRPCAnynsServer.AdminNameRegisterSigned, true
default:
return "", nil, nil, nil, false
}
@ -136,6 +256,22 @@ func (x *drpcAnyns_IsNameAvailableStream) SendAndClose(m *NameAvailableResponse)
return x.CloseSend()
}
type DRPCAnyns_BatchIsNameAvailableStream interface {
drpc.Stream
SendAndClose(*BatchNameAvailableResponse) error
}
type drpcAnyns_BatchIsNameAvailableStream struct {
drpc.Stream
}
func (x *drpcAnyns_BatchIsNameAvailableStream) SendAndClose(m *BatchNameAvailableResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCAnyns_GetNameByAddressStream interface {
drpc.Stream
SendAndClose(*NameByAddressResponse) error
@ -151,3 +287,67 @@ func (x *drpcAnyns_GetNameByAddressStream) SendAndClose(m *NameByAddressResponse
}
return x.CloseSend()
}
type DRPCAnyns_BatchGetNameByAddressStream interface {
drpc.Stream
SendAndClose(*BatchNameByAddressResponse) error
}
type drpcAnyns_BatchGetNameByAddressStream struct {
drpc.Stream
}
func (x *drpcAnyns_BatchGetNameByAddressStream) SendAndClose(m *BatchNameByAddressResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCAnyns_GetNameByAnyIdStream interface {
drpc.Stream
SendAndClose(*NameByAddressResponse) error
}
type drpcAnyns_GetNameByAnyIdStream struct {
drpc.Stream
}
func (x *drpcAnyns_GetNameByAnyIdStream) SendAndClose(m *NameByAddressResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCAnyns_BatchGetNameByAnyIdStream interface {
drpc.Stream
SendAndClose(*BatchNameByAddressResponse) error
}
type drpcAnyns_BatchGetNameByAnyIdStream struct {
drpc.Stream
}
func (x *drpcAnyns_BatchGetNameByAnyIdStream) SendAndClose(m *BatchNameByAddressResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCAnyns_AdminNameRegisterSignedStream interface {
drpc.Stream
SendAndClose(*OperationResponse) error
}
type drpcAnyns_AdminNameRegisterSignedStream struct {
drpc.Stream
}
func (x *drpcAnyns_AdminNameRegisterSignedStream) SendAndClose(m *OperationResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_nameservice_nameserviceproto_protos_nameservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}

View file

@ -2,35 +2,63 @@ syntax = "proto3";
option go_package = "nameservice/nameserviceproto";
//import "google/protobuf/timestamp.proto";
import "nameservice/nameserviceproto/protos/nameservice_aa.proto";
message NameAvailableRequest {
// Name including .any suffix
string fullName = 1;
}
message BatchNameAvailableRequest {
// Names including .any suffix
repeated string fullNames = 1;
}
message NameByAddressRequest {
// An Ethereum address that owns that name
string ownerEthAddress = 1;
// EOA -> SCW -> name
// A SCW Ethereum address that owns that name
string ownerScwEthAddress = 1;
}
message BatchNameByAddressRequest {
// EOA -> SCW -> name
// A SCW Ethereum address that owns that name
repeated string ownerScwEthAddresses = 1;
}
message NameByAnyIdRequest {
string anyAddress = 1;
}
message BatchNameByAnyIdRequest {
repeated string anyAddresses = 1;
}
message NameAvailableResponse {
bool available = 1;
// An Ethereum address that owns that name
// EOA -> SCW -> name
// This field is non-empty only if name is "already registered"
string ownerEthAddress = 2;
string ownerScwEthAddress = 2;
// This field is non-empty only if name is "already registered"
string ownerEthAddress = 3;
// A content hash attached to this name
// This field is non-empty only if name is "already registered"
string ownerAnyAddress = 3;
string ownerAnyAddress = 4;
// A SpaceID attached to this name
// This field is non-empty only if name is "already registered"
string spaceId = 4;
string spaceId = 5;
// doestn't work with marashalling/unmarshalling
// doesn't work with marashalling/unmarshalling
//google.protobuf.Timestamp nameExpires = 5 [(gogoproto.stdtime) = true];
int64 nameExpires = 5;
int64 nameExpires = 6;
}
message BatchNameAvailableResponse {
repeated NameAvailableResponse results = 1;
}
message NameByAddressResponse {
@ -39,8 +67,24 @@ message NameByAddressResponse {
string name = 2;
}
service Anyns {
// Check if name is free or get the attached information if not
rpc IsNameAvailable(NameAvailableRequest) returns (NameAvailableResponse) {}
rpc GetNameByAddress(NameByAddressRequest) returns (NameByAddressResponse) {}
message BatchNameByAddressResponse {
repeated NameByAddressResponse results = 1;
}
service Anyns {
// Lookup: name -> address
rpc IsNameAvailable(NameAvailableRequest) returns (NameAvailableResponse) {}
rpc BatchIsNameAvailable(BatchNameAvailableRequest) returns (BatchNameAvailableResponse) {}
// Reverse lookup: address -> name
rpc GetNameByAddress(NameByAddressRequest) returns (NameByAddressResponse) {}
rpc BatchGetNameByAddress(BatchNameByAddressRequest) returns (BatchNameByAddressResponse) {}
// Reverse lookup: ANY ID -> name
rpc GetNameByAnyId(NameByAnyIdRequest) returns (NameByAddressResponse) {}
rpc BatchGetNameByAnyId(BatchNameByAnyIdRequest) returns (BatchNameByAddressResponse) {}
// Register new name for the user (on behalf of the user)
// Anytype CAN only register names for users, but can not transfer or update them!
rpc AdminNameRegisterSigned(NameRegisterRequestSigned) returns (OperationResponse) {}
}

View file

@ -79,6 +79,8 @@ message CreateUserOperationRequest {
string ownerEthAddress = 4;
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
string ownerAnyID = 5;
// all operations currently are towards single name, please specify it
@ -98,6 +100,45 @@ message NameRegisterRequest {
string fullName = 1;
// A content hash attached to this name
// This should not be empty!
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
string ownerAnyAddress = 2;
// An Ethereum address that owns that name
string ownerEthAddress = 3;
// if false -> name ownership will belong to ownerEthAddress
// if true -> name ownership will belong to SCW of ownerEthAddress (AccountAbstraction)
bool registerToSmartContractWallet = 4;
// How many months to register the name for
uint32 registerPeriodMonths = 5;
// Example:
// 1 - register alice.any -> ANYID123123
// 2 - register xxxx.any -> ANYID123123
// reverse resolve ANYID123123 will return xxxx.any
//
// TODO: currently by default "true"
// bool updateReverseResolver = 4;
}
message NameRegisterRequestSigned {
// NameRegisterRequest struct
bytes payload = 1;
// payload signed by payload.ownerEthAddress
bytes signature = 2;
}
message NameRegisterForSpaceRequest {
string fullName = 1;
// A content hash attached to this name
// This should not be empty!
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
string ownerAnyAddress = 2;
// An Ethereum address that owns that name
@ -105,6 +146,9 @@ message NameRegisterRequest {
// A SpaceID attached to this name
string spaceId = 4;
// How many months to register the name for
uint32 registerPeriodMonths = 5;
}
message GetOperationStatusRequest {
@ -153,7 +197,12 @@ service AnynsAccountAbstraction {
// 2. sign it with your Ethereum private key
// 3. send it using CreateUserOperation
// 4. check operation status using GetOperation
//
// Register new name for my Any identity
rpc GetDataNameRegister(NameRegisterRequest) returns (GetDataNameRegisterResponse) {}
// Register new name and attach Space ID to it
rpc GetDataNameRegisterForSpace(NameRegisterForSpaceRequest) returns (GetDataNameRegisterResponse) {}
// TODO
//rpc GetDataNameUpdate(NameUpdateRequest) returns (GetDataNameRegisterResponse) {}

View file

@ -244,6 +244,9 @@ var defaultProtoChecker = handshake.ProtoChecker{
}
func (p *peer) serve(conn net.Conn) (err error) {
defer func() {
_ = conn.Close()
}()
hsCtx, cancel := context.WithTimeout(p.Context(), time.Second*20)
if _, err = handshake.IncomingProtoHandshake(hsCtx, conn, defaultProtoChecker); err != nil {
cancel()

15
net/rpc/limiter/config.go Normal file
View file

@ -0,0 +1,15 @@
package limiter
type ConfigGetter interface {
GetLimiterConf() Config
}
type Tokens struct {
TokensPerSecond int `yaml:"rps"`
MaxTokens int `yaml:"burst"`
}
type Config struct {
DefaultTokens Tokens `yaml:"default"`
ResponseTokens map[string]Tokens `yaml:"rpc"`
}

130
net/rpc/limiter/limiter.go Normal file
View file

@ -0,0 +1,130 @@
//go:generate mockgen -destination mock_limiter/mock_limiter.go github.com/anyproto/any-sync/net/rpc/limiter RpcLimiter
package limiter
import (
"context"
"strings"
"sync"
"time"
"golang.org/x/time/rate"
"storj.io/drpc"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/net/peer"
"github.com/anyproto/any-sync/net/rpc/limiter/limiterproto"
"github.com/anyproto/any-sync/util/periodicsync"
)
const (
peerCheckInterval = 10 * time.Second
checkTimeout = 2 * time.Second
)
var log = logger.NewNamed(CName)
const CName = "common.rpc.limiter"
type RpcLimiter interface {
app.ComponentRunnable
// WrapDRPCHandler wraps the given drpc.Handler with additional functionality
WrapDRPCHandler(handler drpc.Handler) drpc.Handler
}
func New() RpcLimiter {
return &limiter{
limiters: make(map[string]*peerLimiter),
peerCheckInterval: peerCheckInterval,
checkTimeout: checkTimeout,
}
}
type peerLimiter struct {
*rate.Limiter
lastUsage time.Time
}
type limiter struct {
drpc.Handler
limiters map[string]*peerLimiter
periodicLoop periodicsync.PeriodicSync
peerCheckInterval time.Duration
checkTimeout time.Duration
cfg Config
mx sync.Mutex
}
func (h *limiter) Run(ctx context.Context) (err error) {
h.periodicLoop.Run()
return nil
}
func (h *limiter) Close(ctx context.Context) (err error) {
h.periodicLoop.Close()
return
}
func (h *limiter) Init(a *app.App) (err error) {
h.periodicLoop = periodicsync.NewPeriodicSyncDuration(h.peerCheckInterval, h.checkTimeout, h.peerLoop, log)
h.cfg = a.MustComponent("config").(ConfigGetter).GetLimiterConf()
return nil
}
func (h *limiter) Name() (name string) {
return CName
}
func (h *limiter) peerLoop(ctx context.Context) error {
h.mx.Lock()
defer h.mx.Unlock()
for rpcPeer, lim := range h.limiters {
if time.Since(lim.lastUsage) > h.peerCheckInterval {
delete(h.limiters, rpcPeer)
}
}
return nil
}
func (h *limiter) WrapDRPCHandler(handler drpc.Handler) drpc.Handler {
h.mx.Lock()
defer h.mx.Unlock()
h.Handler = handler
return h
}
func (h *limiter) HandleRPC(stream drpc.Stream, rpc string) (err error) {
peerId, err := peer.CtxPeerId(stream.Context())
if err != nil {
return err
}
lim := h.getPeerLimiter(peerId, rpc)
if !lim.Allow() {
return limiterproto.ErrLimitExceeded
}
return h.Handler.HandleRPC(stream, rpc)
}
func (h *limiter) getLimits(rpc string) Tokens {
if tokens, exists := h.cfg.ResponseTokens[rpc]; exists {
return tokens
}
return h.cfg.DefaultTokens
}
func (h *limiter) getPeerLimiter(peerId string, rpc string) *peerLimiter {
// rpc looks like this /anyNodeSync.NodeSync/PartitionSync
rpcPeer := strings.Join([]string{peerId, rpc}, "-")
h.mx.Lock()
defer h.mx.Unlock()
lim, ok := h.limiters[rpcPeer]
if !ok {
limits := h.getLimits(rpc)
lim = &peerLimiter{
Limiter: rate.NewLimiter(rate.Limit(limits.TokensPerSecond), limits.MaxTokens),
}
h.limiters[rpcPeer] = lim
}
lim.lastUsage = time.Now()
return lim
}

View file

@ -0,0 +1,181 @@
package limiter
import (
"context"
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/require"
"storj.io/drpc"
"github.com/anyproto/any-sync/net/peer"
"github.com/anyproto/any-sync/net/rpc/limiter/limiterproto"
)
var ctx = context.Background()
type mockHandler struct {
calls atomic.Int32
}
type mockStream struct {
ctx context.Context
}
func (m mockStream) Context() context.Context {
return m.ctx
}
func (m mockStream) MsgSend(msg drpc.Message, enc drpc.Encoding) error {
return nil
}
func (m mockStream) MsgRecv(msg drpc.Message, enc drpc.Encoding) error {
return nil
}
func (m mockStream) CloseSend() error {
return nil
}
func (m mockStream) Close() error {
return nil
}
func (m *mockHandler) HandleRPC(stream drpc.Stream, rpc string) (err error) {
m.calls.Add(1)
return nil
}
func TestLimiter_Synchronous(t *testing.T) {
lim := New().(*limiter)
handler := &mockHandler{}
lim.cfg = Config{
DefaultTokens: Tokens{
TokensPerSecond: 100,
MaxTokens: 100,
},
ResponseTokens: map[string]Tokens{
"rpc": {
TokensPerSecond: 10,
MaxTokens: 1,
},
},
}
lim.peerCheckInterval = 10 * time.Millisecond
wrapped := lim.WrapDRPCHandler(handler)
// rpc call allows only one token max, so it should let only first call
// for second one we should wait 100 ms
firstStream := mockStream{ctx: peer.CtxWithPeerId(ctx, "peer1")}
// check that we are using specific timeout
err := wrapped.HandleRPC(firstStream, "rpc")
require.NoError(t, err)
err = wrapped.HandleRPC(firstStream, "rpc")
require.Equal(t, limiterproto.ErrLimitExceeded, err)
// second stream should not affect the first one
secondStream := mockStream{ctx: peer.CtxWithPeerId(ctx, "peer2")}
err = wrapped.HandleRPC(secondStream, "rpc")
require.NoError(t, err)
// after 100 ms new token has been generated
time.Sleep(100 * time.Millisecond)
err = wrapped.HandleRPC(firstStream, "rpc")
require.NoError(t, err)
time.Sleep(10 * time.Millisecond)
// checking that peer loop cleaned the map
err = lim.peerLoop(ctx)
require.NoError(t, err)
// now we should be able to call again, because we cleared the map
err = wrapped.HandleRPC(firstStream, "rpc")
require.NoError(t, err)
// but limit of 1 sec is not enough to clean the map
time.Sleep(1 * time.Millisecond)
err = wrapped.HandleRPC(firstStream, "rpc")
require.Equal(t, limiterproto.ErrLimitExceeded, err)
}
func TestLimiter_Concurrent_NoBursts(t *testing.T) {
lim := New().(*limiter)
handler := &mockHandler{}
var (
targetRps = 10
// peerRps should be greater than targetRps
peerRps = 100
reqDelay = time.Duration(1000/peerRps) * time.Millisecond
)
lim.cfg = Config{
DefaultTokens: Tokens{
TokensPerSecond: targetRps,
MaxTokens: 1,
},
}
wrapped := lim.WrapDRPCHandler(handler)
firstStream := mockStream{ctx: peer.CtxWithPeerId(ctx, "peer1")}
secondStream := mockStream{ctx: peer.CtxWithPeerId(ctx, "peer2")}
waitFirst := make(chan struct{})
waitSecond := make(chan struct{})
go func() {
for i := 0; i < peerRps; i++ {
time.Sleep(reqDelay)
_ = wrapped.HandleRPC(firstStream, "rpc")
}
close(waitFirst)
}()
go func() {
for i := 0; i < peerRps; i++ {
time.Sleep(reqDelay)
_ = wrapped.HandleRPC(secondStream, "rpc")
}
close(waitSecond)
}()
<-waitFirst
<-waitSecond
// 2 for number of peers and 2 for error margin (delays etc)
maxCalls := 2 * 2 * targetRps
require.Greater(t, maxCalls, int(handler.calls.Load()))
}
func TestLimiter_Concurrent_Bursts(t *testing.T) {
lim := New().(*limiter)
handler := &mockHandler{}
var (
targetRps = 10
// bursts are not affected by rps limit
burst = 10
// peerRps should be greater than targetRps + burst
peerRps = 100
reqDelay = time.Duration(1000/peerRps) * time.Millisecond
)
lim.cfg = Config{
DefaultTokens: Tokens{
TokensPerSecond: targetRps,
MaxTokens: burst,
},
}
wrapped := lim.WrapDRPCHandler(handler)
firstStream := mockStream{ctx: peer.CtxWithPeerId(ctx, "peer1")}
secondStream := mockStream{ctx: peer.CtxWithPeerId(ctx, "peer2")}
waitFirst := make(chan struct{})
waitSecond := make(chan struct{})
go func() {
for i := 0; i < peerRps; i++ {
time.Sleep(reqDelay)
_ = wrapped.HandleRPC(firstStream, "rpc")
}
close(waitFirst)
}()
go func() {
for i := 0; i < peerRps; i++ {
time.Sleep(reqDelay)
_ = wrapped.HandleRPC(secondStream, "rpc")
}
close(waitSecond)
}()
<-waitFirst
<-waitSecond
// 2 for number of peers and 2 for error margin (delays etc)
maxCalls := 2 * 2 * (targetRps + burst)
minCalls := 2 * (targetRps + burst)
require.Greater(t, maxCalls, int(handler.calls.Load()))
require.LessOrEqual(t, minCalls, int(handler.calls.Load()))
}

View file

@ -0,0 +1,13 @@
package limiterproto
import (
"errors"
"github.com/anyproto/any-sync/net/rpc/rpcerr"
)
var (
errGroup = rpcerr.ErrGroup(ErrCodes_ErrorOffset)
ErrLimitExceeded = errGroup.Register(errors.New("rate limit exceeded"), uint64(ErrCodes_RateLimitExceeded))
)

View file

@ -0,0 +1,68 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: net/rpc/limiter/limiterproto/protos/limiter.proto
package limiterproto
import (
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type ErrCodes int32
const (
ErrCodes_RateLimitExceeded ErrCodes = 0
ErrCodes_ErrorOffset ErrCodes = 700
)
var ErrCodes_name = map[int32]string{
0: "RateLimitExceeded",
700: "ErrorOffset",
}
var ErrCodes_value = map[string]int32{
"RateLimitExceeded": 0,
"ErrorOffset": 700,
}
func (x ErrCodes) String() string {
return proto.EnumName(ErrCodes_name, int32(x))
}
func (ErrCodes) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_43f29163996a95d8, []int{0}
}
func init() {
proto.RegisterEnum("limiter.ErrCodes", ErrCodes_name, ErrCodes_value)
}
func init() {
proto.RegisterFile("net/rpc/limiter/limiterproto/protos/limiter.proto", fileDescriptor_43f29163996a95d8)
}
var fileDescriptor_43f29163996a95d8 = []byte{
// 147 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0xcc, 0x4b, 0x2d, 0xd1,
0x2f, 0x2a, 0x48, 0xd6, 0xcf, 0xc9, 0xcc, 0xcd, 0x2c, 0x49, 0x2d, 0x82, 0xd1, 0x05, 0x45, 0xf9,
0x25, 0xf9, 0xfa, 0x60, 0xb2, 0x18, 0x26, 0xa6, 0x07, 0xe6, 0x0a, 0xb1, 0x43, 0xb9, 0x5a, 0xc6,
0x5c, 0x1c, 0xae, 0x45, 0x45, 0xce, 0xf9, 0x29, 0xa9, 0xc5, 0x42, 0xa2, 0x5c, 0x82, 0x41, 0x89,
0x25, 0xa9, 0x3e, 0x20, 0x29, 0xd7, 0x8a, 0xe4, 0xd4, 0xd4, 0x94, 0xd4, 0x14, 0x01, 0x06, 0x21,
0x01, 0x2e, 0x6e, 0xd7, 0xa2, 0xa2, 0xfc, 0x22, 0xff, 0xb4, 0xb4, 0xe2, 0xd4, 0x12, 0x81, 0x3d,
0xac, 0x4e, 0x66, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3,
0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0x25, 0x83, 0xcf,
0x29, 0x49, 0x6c, 0x60, 0xca, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x1e, 0x6b, 0xb3, 0x13, 0xb1,
0x00, 0x00, 0x00,
}

View file

@ -0,0 +1,8 @@
syntax = "proto3";
package limiter;
option go_package = "net/rpc/limiter/limiterproto";
enum ErrCodes {
RateLimitExceeded = 0;
ErrorOffset = 700;
}

View file

@ -0,0 +1,112 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/anyproto/any-sync/net/rpc/limiter (interfaces: RpcLimiter)
//
// Generated by this command:
//
// mockgen -destination mock_limiter/mock_limiter.go github.com/anyproto/any-sync/net/rpc/limiter RpcLimiter
//
// Package mock_limiter is a generated GoMock package.
package mock_limiter
import (
context "context"
reflect "reflect"
app "github.com/anyproto/any-sync/app"
gomock "go.uber.org/mock/gomock"
drpc "storj.io/drpc"
)
// MockRpcLimiter is a mock of RpcLimiter interface.
type MockRpcLimiter struct {
ctrl *gomock.Controller
recorder *MockRpcLimiterMockRecorder
}
// MockRpcLimiterMockRecorder is the mock recorder for MockRpcLimiter.
type MockRpcLimiterMockRecorder struct {
mock *MockRpcLimiter
}
// NewMockRpcLimiter creates a new mock instance.
func NewMockRpcLimiter(ctrl *gomock.Controller) *MockRpcLimiter {
mock := &MockRpcLimiter{ctrl: ctrl}
mock.recorder = &MockRpcLimiterMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockRpcLimiter) EXPECT() *MockRpcLimiterMockRecorder {
return m.recorder
}
// Close mocks base method.
func (m *MockRpcLimiter) Close(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Close", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Close indicates an expected call of Close.
func (mr *MockRpcLimiterMockRecorder) Close(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockRpcLimiter)(nil).Close), arg0)
}
// Init mocks base method.
func (m *MockRpcLimiter) Init(arg0 *app.App) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Init", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Init indicates an expected call of Init.
func (mr *MockRpcLimiterMockRecorder) Init(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockRpcLimiter)(nil).Init), arg0)
}
// Name mocks base method.
func (m *MockRpcLimiter) Name() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Name")
ret0, _ := ret[0].(string)
return ret0
}
// Name indicates an expected call of Name.
func (mr *MockRpcLimiterMockRecorder) Name() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockRpcLimiter)(nil).Name))
}
// Run mocks base method.
func (m *MockRpcLimiter) Run(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Run", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Run indicates an expected call of Run.
func (mr *MockRpcLimiterMockRecorder) Run(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockRpcLimiter)(nil).Run), arg0)
}
// WrapDRPCHandler mocks base method.
func (m *MockRpcLimiter) WrapDRPCHandler(arg0 drpc.Handler) drpc.Handler {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "WrapDRPCHandler", arg0)
ret0, _ := ret[0].(drpc.Handler)
return ret0
}
// WrapDRPCHandler indicates an expected call of WrapDRPCHandler.
func (mr *MockRpcLimiterMockRecorder) WrapDRPCHandler(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WrapDRPCHandler", reflect.TypeOf((*MockRpcLimiter)(nil).WrapDRPCHandler), arg0)
}

View file

@ -43,7 +43,7 @@ func Unwrap(e error) error {
}
err, ok := errsMap[code]
if !ok {
return drpcerr.WithCode(fmt.Errorf("unexpected error: %v; code: %d", err, code), code)
return drpcerr.WithCode(fmt.Errorf("unexpected error: %w; code: %d", e, code), code)
}
return err
}

View file

@ -2,12 +2,15 @@ package server
import (
"context"
"net"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/metric"
"github.com/anyproto/any-sync/net/rpc"
"github.com/anyproto/any-sync/net/rpc/limiter"
"go.uber.org/zap"
"net"
"storj.io/drpc"
"storj.io/drpc/drpcmanager"
"storj.io/drpc/drpcmux"
@ -34,8 +37,9 @@ type DRPCServer interface {
type drpcServer struct {
drpcServer *drpcserver.Server
*drpcmux.Mux
config rpc.Config
metric metric.Metric
config rpc.Config
metric metric.Metric
limiter limiter.RpcLimiter
}
type DRPCHandlerWrapper func(handler drpc.Handler) drpc.Handler
@ -47,12 +51,16 @@ func (s *drpcServer) Name() (name string) {
func (s *drpcServer) Init(a *app.App) (err error) {
s.config = a.MustComponent("config").(rpc.ConfigGetter).GetDrpc()
s.metric, _ = a.Component(metric.CName).(metric.Metric)
s.limiter, _ = a.Component(limiter.CName).(limiter.RpcLimiter)
s.Mux = drpcmux.New()
var handler drpc.Handler
handler = s
if s.limiter != nil {
handler = s.limiter.WrapDRPCHandler(handler)
}
if s.metric != nil {
handler = s.metric.WrapDRPCHandler(s)
handler = s.metric.WrapDRPCHandler(handler)
}
bufSize := s.config.Stream.MaxMsgSizeMb * (1 << 20)
s.drpcServer = drpcserver.NewWithOptions(handler, drpcserver.Options{Manager: drpcmanager.Options{

View file

@ -28,11 +28,11 @@ var (
// ProtoVersion 1 - version with yamux over tcp and quic
// ProtoVersion 2 - acl compatible version
// ProtoVersion 3 - acl with breaking changes / multiplayer
ProtoVersion = uint32(2)
ProtoVersion = uint32(3)
)
var (
compatibleVersions = []uint32{ProtoVersion, 3}
compatibleVersions = []uint32{2, ProtoVersion}
)
func New() SecureService {

View file

@ -4,18 +4,20 @@ import (
"context"
"crypto/tls"
"fmt"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/net/secureservice"
"github.com/anyproto/any-sync/net/transport"
"net"
"sync"
"time"
libp2crypto "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls"
"github.com/quic-go/quic-go"
"go.uber.org/zap"
"net"
"sync"
"time"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/net/secureservice"
"github.com/anyproto/any-sync/net/transport"
)
const CName = "net.transport.quic"
@ -139,6 +141,9 @@ func (q *quicTransport) Dial(ctx context.Context, addr string) (mc transport.Mul
cctx, err := q.secure.HandshakeOutbound(ctx, stream, remotePeerId.String())
if err != nil {
defer func() {
_ = qConn.CloseWithError(3, "outbound handshake failed")
}()
return nil, err
}
@ -189,6 +194,9 @@ func (q *quicTransport) accept(conn quic.Connection) (err error) {
}()
cctx, err := q.secure.HandshakeInbound(ctx, stream, remotePeerId.String())
if err != nil {
defer func() {
_ = conn.CloseWithError(3, "inbound handshake failed")
}()
return
}
mc := newConn(cctx, conn)

View file

@ -0,0 +1,100 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/anyproto/any-sync/node/nodeclient (interfaces: NodeClient)
//
// Generated by this command:
//
// mockgen -destination mock_nodeclient/mock_nodeclient.go github.com/anyproto/any-sync/node/nodeclient NodeClient
//
// Package mock_nodeclient is a generated GoMock package.
package mock_nodeclient
import (
context "context"
reflect "reflect"
app "github.com/anyproto/any-sync/app"
consensusproto "github.com/anyproto/any-sync/consensus/consensusproto"
gomock "go.uber.org/mock/gomock"
)
// MockNodeClient is a mock of NodeClient interface.
type MockNodeClient struct {
ctrl *gomock.Controller
recorder *MockNodeClientMockRecorder
}
// MockNodeClientMockRecorder is the mock recorder for MockNodeClient.
type MockNodeClientMockRecorder struct {
mock *MockNodeClient
}
// NewMockNodeClient creates a new mock instance.
func NewMockNodeClient(ctrl *gomock.Controller) *MockNodeClient {
mock := &MockNodeClient{ctrl: ctrl}
mock.recorder = &MockNodeClientMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockNodeClient) EXPECT() *MockNodeClientMockRecorder {
return m.recorder
}
// AclAddRecord mocks base method.
func (m *MockNodeClient) AclAddRecord(arg0 context.Context, arg1 string, arg2 *consensusproto.RawRecord) (*consensusproto.RawRecordWithId, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AclAddRecord", arg0, arg1, arg2)
ret0, _ := ret[0].(*consensusproto.RawRecordWithId)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AclAddRecord indicates an expected call of AclAddRecord.
func (mr *MockNodeClientMockRecorder) AclAddRecord(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AclAddRecord", reflect.TypeOf((*MockNodeClient)(nil).AclAddRecord), arg0, arg1, arg2)
}
// AclGetRecords mocks base method.
func (m *MockNodeClient) AclGetRecords(arg0 context.Context, arg1, arg2 string) ([]*consensusproto.RawRecordWithId, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AclGetRecords", arg0, arg1, arg2)
ret0, _ := ret[0].([]*consensusproto.RawRecordWithId)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AclGetRecords indicates an expected call of AclGetRecords.
func (mr *MockNodeClientMockRecorder) AclGetRecords(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AclGetRecords", reflect.TypeOf((*MockNodeClient)(nil).AclGetRecords), arg0, arg1, arg2)
}
// Init mocks base method.
func (m *MockNodeClient) Init(arg0 *app.App) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Init", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Init indicates an expected call of Init.
func (mr *MockNodeClientMockRecorder) Init(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockNodeClient)(nil).Init), arg0)
}
// Name mocks base method.
func (m *MockNodeClient) Name() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Name")
ret0, _ := ret[0].(string)
return ret0
}
// Name indicates an expected call of Name.
func (mr *MockNodeClientMockRecorder) Name() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockNodeClient)(nil).Name))
}

View file

@ -0,0 +1,98 @@
//go:generate mockgen -destination mock_nodeclient/mock_nodeclient.go github.com/anyproto/any-sync/node/nodeclient NodeClient
package nodeclient
import (
"context"
"storj.io/drpc"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/commonspace/spacesyncproto"
"github.com/anyproto/any-sync/consensus/consensusproto"
"github.com/anyproto/any-sync/net/pool"
"github.com/anyproto/any-sync/net/rpc/rpcerr"
"github.com/anyproto/any-sync/nodeconf"
)
const CName = "common.node.nodeclient"
func New() NodeClient {
return &nodeClient{}
}
type NodeClient interface {
app.Component
AclGetRecords(ctx context.Context, spaceId, aclHead string) (recs []*consensusproto.RawRecordWithId, err error)
AclAddRecord(ctx context.Context, spaceId string, rec *consensusproto.RawRecord) (recWithId *consensusproto.RawRecordWithId, err error)
}
type nodeClient struct {
pool pool.Service
nodeConf nodeconf.Service
}
func (c *nodeClient) Init(a *app.App) (err error) {
c.pool = a.MustComponent(pool.CName).(pool.Service)
c.nodeConf = a.MustComponent(nodeconf.CName).(nodeconf.Service)
return
}
func (c *nodeClient) Name() (name string) {
return CName
}
func (c *nodeClient) AclGetRecords(ctx context.Context, spaceId, aclHead string) (recs []*consensusproto.RawRecordWithId, err error) {
err = clientDo(c, ctx, spaceId, func(cl spacesyncproto.DRPCSpaceSyncClient) error {
resp, err := cl.AclGetRecords(ctx, &spacesyncproto.AclGetRecordsRequest{
SpaceId: spaceId,
AclHead: aclHead,
})
if err != nil {
return err
}
recs = make([]*consensusproto.RawRecordWithId, len(resp.Records))
for i, rec := range resp.Records {
recs[i] = &consensusproto.RawRecordWithId{}
if err = recs[i].Unmarshal(rec); err != nil {
return err
}
}
return nil
})
return
}
func (c *nodeClient) AclAddRecord(ctx context.Context, spaceId string, rec *consensusproto.RawRecord) (recWithId *consensusproto.RawRecordWithId, err error) {
data, err := rec.Marshal()
if err != nil {
return
}
err = clientDo(c, ctx, spaceId, func(cl spacesyncproto.DRPCSpaceSyncClient) error {
res, err := cl.AclAddRecord(ctx, &spacesyncproto.AclAddRecordRequest{
SpaceId: spaceId,
Payload: data,
})
if err != nil {
return err
}
recWithId = &consensusproto.RawRecordWithId{
Payload: res.Payload,
Id: res.RecordId,
}
return nil
})
return
}
var clientDo = (*nodeClient).doClient
func (c *nodeClient) doClient(ctx context.Context, spaceId string, f func(cl spacesyncproto.DRPCSpaceSyncClient) error) error {
p, err := c.pool.GetOneOf(ctx, c.nodeConf.NodeIds(spaceId))
if err != nil {
return err
}
return p.DoDrpc(ctx, func(conn drpc.Conn) error {
err := f(spacesyncproto.NewDRPCSpaceSyncClient(conn))
return rpcerr.Unwrap(err)
})
}

View file

@ -0,0 +1,92 @@
package nodeclient
import (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"github.com/anyproto/any-sync/commonspace/spacesyncproto"
"github.com/anyproto/any-sync/commonspace/spacesyncproto/mock_spacesyncproto"
"github.com/anyproto/any-sync/consensus/consensusproto"
)
var ctx = context.Background()
type fixture struct {
*nodeClient
ctrl *gomock.Controller
}
func (f *fixture) finish() {
f.ctrl.Finish()
}
func newFixture(t *testing.T) *fixture {
ctrl := gomock.NewController(t)
return &fixture{
nodeClient: New().(*nodeClient),
ctrl: ctrl,
}
}
func TestNodeClient_AclGetRecords(t *testing.T) {
f := newFixture(t)
defer f.finish()
spaceId := "spaceId"
aclHead := "aclHead"
cl := mock_spacesyncproto.NewMockDRPCSpaceSyncClient(f.ctrl)
clientDo = func(client *nodeClient, ctx context.Context, s string, f func(cl spacesyncproto.DRPCSpaceSyncClient) error) error {
return f(cl)
}
var (
expectedRecs []*consensusproto.RawRecordWithId
expectedByteRecs [][]byte
total = 5
)
for i := 0; i < total; i++ {
expectedRecs = append(expectedRecs, &consensusproto.RawRecordWithId{
Id: fmt.Sprint(i),
})
marshalled, err := expectedRecs[i].Marshal()
require.NoError(t, err)
expectedByteRecs = append(expectedByteRecs, marshalled)
}
cl.EXPECT().AclGetRecords(ctx, &spacesyncproto.AclGetRecordsRequest{
SpaceId: spaceId,
AclHead: aclHead,
}).Return(&spacesyncproto.AclGetRecordsResponse{Records: expectedByteRecs}, nil)
recs, err := f.AclGetRecords(ctx, spaceId, aclHead)
require.NoError(t, err)
require.Equal(t, expectedRecs, recs)
}
func TestNodeClient_AclAddRecords(t *testing.T) {
f := newFixture(t)
defer f.finish()
spaceId := "spaceId"
cl := mock_spacesyncproto.NewMockDRPCSpaceSyncClient(f.ctrl)
clientDo = func(client *nodeClient, ctx context.Context, s string, f func(cl spacesyncproto.DRPCSpaceSyncClient) error) error {
return f(cl)
}
sendRec := &consensusproto.RawRecord{
AcceptorTimestamp: 10,
}
data, err := sendRec.Marshal()
require.NoError(t, err)
expectedRec := &consensusproto.RawRecordWithId{
Id: "recId",
Payload: data,
}
cl.EXPECT().AclAddRecord(ctx, &spacesyncproto.AclAddRecordRequest{
SpaceId: spaceId,
Payload: data,
}).Return(&spacesyncproto.AclAddRecordResponse{RecordId: expectedRec.Id, Payload: expectedRec.Payload}, nil)
rec, err := f.AclAddRecord(ctx, spaceId, sendRec)
require.NoError(t, err)
require.Equal(t, expectedRec, rec)
}

View file

@ -5,6 +5,7 @@
//
// mockgen -source paymentservice/paymentserviceclient/paymentserviceclient.go
//
// Package mock_paymentserviceclient is a generated GoMock package.
package mock_paymentserviceclient
@ -55,18 +56,49 @@ func (mr *MockAnyPpClientServiceMockRecorder) BuySubscription(ctx, in any) *gomo
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuySubscription", reflect.TypeOf((*MockAnyPpClientService)(nil).BuySubscription), ctx, in)
}
// Close mocks base method.
func (m *MockAnyPpClientService) Close(ctx context.Context) error {
// FinalizeSubscription mocks base method.
func (m *MockAnyPpClientService) FinalizeSubscription(ctx context.Context, in *paymentserviceproto.FinalizeSubscriptionRequestSigned) (*paymentserviceproto.FinalizeSubscriptionResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Close", ctx)
ret0, _ := ret[0].(error)
return ret0
ret := m.ctrl.Call(m, "FinalizeSubscription", ctx, in)
ret0, _ := ret[0].(*paymentserviceproto.FinalizeSubscriptionResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Close indicates an expected call of Close.
func (mr *MockAnyPpClientServiceMockRecorder) Close(ctx any) *gomock.Call {
// FinalizeSubscription indicates an expected call of FinalizeSubscription.
func (mr *MockAnyPpClientServiceMockRecorder) FinalizeSubscription(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockAnyPpClientService)(nil).Close), ctx)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FinalizeSubscription", reflect.TypeOf((*MockAnyPpClientService)(nil).FinalizeSubscription), ctx, in)
}
// GetAllTiers mocks base method.
func (m *MockAnyPpClientService) GetAllTiers(ctx context.Context, in *paymentserviceproto.GetTiersRequestSigned) (*paymentserviceproto.GetTiersResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAllTiers", ctx, in)
ret0, _ := ret[0].(*paymentserviceproto.GetTiersResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAllTiers indicates an expected call of GetAllTiers.
func (mr *MockAnyPpClientServiceMockRecorder) GetAllTiers(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllTiers", reflect.TypeOf((*MockAnyPpClientService)(nil).GetAllTiers), ctx, in)
}
// GetSubscriptionPortalLink mocks base method.
func (m *MockAnyPpClientService) GetSubscriptionPortalLink(ctx context.Context, in *paymentserviceproto.GetSubscriptionPortalLinkRequestSigned) (*paymentserviceproto.GetSubscriptionPortalLinkResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSubscriptionPortalLink", ctx, in)
ret0, _ := ret[0].(*paymentserviceproto.GetSubscriptionPortalLinkResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetSubscriptionPortalLink indicates an expected call of GetSubscriptionPortalLink.
func (mr *MockAnyPpClientServiceMockRecorder) GetSubscriptionPortalLink(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubscriptionPortalLink", reflect.TypeOf((*MockAnyPpClientService)(nil).GetSubscriptionPortalLink), ctx, in)
}
// GetSubscriptionStatus mocks base method.
@ -84,6 +116,21 @@ func (mr *MockAnyPpClientServiceMockRecorder) GetSubscriptionStatus(ctx, in any)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubscriptionStatus", reflect.TypeOf((*MockAnyPpClientService)(nil).GetSubscriptionStatus), ctx, in)
}
// GetVerificationEmail mocks base method.
func (m *MockAnyPpClientService) GetVerificationEmail(ctx context.Context, in *paymentserviceproto.GetVerificationEmailRequestSigned) (*paymentserviceproto.GetVerificationEmailResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetVerificationEmail", ctx, in)
ret0, _ := ret[0].(*paymentserviceproto.GetVerificationEmailResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetVerificationEmail indicates an expected call of GetVerificationEmail.
func (mr *MockAnyPpClientServiceMockRecorder) GetVerificationEmail(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVerificationEmail", reflect.TypeOf((*MockAnyPpClientService)(nil).GetVerificationEmail), ctx, in)
}
// Init mocks base method.
func (m *MockAnyPpClientService) Init(a *app.App) error {
m.ctrl.T.Helper()
@ -98,6 +145,21 @@ func (mr *MockAnyPpClientServiceMockRecorder) Init(a any) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockAnyPpClientService)(nil).Init), a)
}
// IsNameValid mocks base method.
func (m *MockAnyPpClientService) IsNameValid(ctx context.Context, in *paymentserviceproto.IsNameValidRequest) (*paymentserviceproto.IsNameValidResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IsNameValid", ctx, in)
ret0, _ := ret[0].(*paymentserviceproto.IsNameValidResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// IsNameValid indicates an expected call of IsNameValid.
func (mr *MockAnyPpClientServiceMockRecorder) IsNameValid(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsNameValid", reflect.TypeOf((*MockAnyPpClientService)(nil).IsNameValid), ctx, in)
}
// Name mocks base method.
func (m *MockAnyPpClientService) Name() string {
m.ctrl.T.Helper()
@ -112,16 +174,32 @@ func (mr *MockAnyPpClientServiceMockRecorder) Name() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockAnyPpClientService)(nil).Name))
}
// Run mocks base method.
func (m *MockAnyPpClientService) Run(ctx context.Context) error {
// VerifyAppStoreReceipt mocks base method.
func (m *MockAnyPpClientService) VerifyAppStoreReceipt(ctx context.Context, in *paymentserviceproto.VerifyAppStoreReceiptRequestSigned) (*paymentserviceproto.VerifyAppStoreReceiptResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Run", ctx)
ret0, _ := ret[0].(error)
return ret0
ret := m.ctrl.Call(m, "VerifyAppStoreReceipt", ctx, in)
ret0, _ := ret[0].(*paymentserviceproto.VerifyAppStoreReceiptResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Run indicates an expected call of Run.
func (mr *MockAnyPpClientServiceMockRecorder) Run(ctx any) *gomock.Call {
// VerifyAppStoreReceipt indicates an expected call of VerifyAppStoreReceipt.
func (mr *MockAnyPpClientServiceMockRecorder) VerifyAppStoreReceipt(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockAnyPpClientService)(nil).Run), ctx)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyAppStoreReceipt", reflect.TypeOf((*MockAnyPpClientService)(nil).VerifyAppStoreReceipt), ctx, in)
}
// VerifyEmail mocks base method.
func (m *MockAnyPpClientService) VerifyEmail(ctx context.Context, in *paymentserviceproto.VerifyEmailRequestSigned) (*paymentserviceproto.VerifyEmailResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "VerifyEmail", ctx, in)
ret0, _ := ret[0].(*paymentserviceproto.VerifyEmailResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// VerifyEmail indicates an expected call of VerifyEmail.
func (mr *MockAnyPpClientServiceMockRecorder) VerifyEmail(ctx, in any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyEmail", reflect.TypeOf((*MockAnyPpClientService)(nil).VerifyEmail), ctx, in)
}

View file

@ -2,8 +2,10 @@ package paymentserviceclient
import (
"context"
"errors"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/net/pool"
"github.com/anyproto/any-sync/net/rpc/rpcerr"
"github.com/anyproto/any-sync/nodeconf"
@ -13,13 +15,22 @@ import (
const CName = "any-pp.drpcclient"
var log = logger.NewNamed(CName)
/*
* This client component can be used to access the Any Payment Processing node
* from other components.
*/
type AnyPpClientService interface {
GetSubscriptionStatus(ctx context.Context, in *pp.GetSubscriptionRequestSigned) (out *pp.GetSubscriptionResponse, err error)
IsNameValid(ctx context.Context, in *pp.IsNameValidRequest) (out *pp.IsNameValidResponse, err error)
BuySubscription(ctx context.Context, in *pp.BuySubscriptionRequestSigned) (out *pp.BuySubscriptionResponse, err error)
GetSubscriptionPortalLink(ctx context.Context, in *pp.GetSubscriptionPortalLinkRequestSigned) (out *pp.GetSubscriptionPortalLinkResponse, err error)
GetVerificationEmail(ctx context.Context, in *pp.GetVerificationEmailRequestSigned) (out *pp.GetVerificationEmailResponse, err error)
VerifyEmail(ctx context.Context, in *pp.VerifyEmailRequestSigned) (out *pp.VerifyEmailResponse, err error)
FinalizeSubscription(ctx context.Context, in *pp.FinalizeSubscriptionRequestSigned) (out *pp.FinalizeSubscriptionResponse, err error)
GetAllTiers(ctx context.Context, in *pp.GetTiersRequestSigned) (out *pp.GetTiersResponse, err error)
VerifyAppStoreReceipt(ctx context.Context, in *pp.VerifyAppStoreReceiptRequestSigned) (out *pp.VerifyAppStoreReceiptResponse, err error)
app.Component
}
@ -44,10 +55,15 @@ func New() AnyPpClientService {
}
func (s *service) doClient(ctx context.Context, fn func(cl pp.DRPCAnyPaymentProcessingClient) error) error {
if len(s.nodeconf.PaymentProcessingNodePeers()) == 0 {
log.Error("no payment processing peers configured")
return errors.New("no paymentProcessingNode peers configured")
}
// it will try to connect to the Payment Node
// please use "paymentProcessingNode" type of node in the config (in the network.nodes array)
peer, err := s.pool.Get(ctx, s.nodeconf.PaymentProcessingNodePeers()[0])
peer, err := s.pool.GetOneOf(ctx, s.nodeconf.PaymentProcessingNodePeers())
if err != nil {
return err
}
@ -80,3 +96,73 @@ func (s *service) BuySubscription(ctx context.Context, in *pp.BuySubscriptionReq
})
return
}
func (s *service) GetSubscriptionPortalLink(ctx context.Context, in *pp.GetSubscriptionPortalLinkRequestSigned) (out *pp.GetSubscriptionPortalLinkResponse, err error) {
err = s.doClient(ctx, func(cl pp.DRPCAnyPaymentProcessingClient) error {
if out, err = cl.GetSubscriptionPortalLink(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
func (s *service) GetVerificationEmail(ctx context.Context, in *pp.GetVerificationEmailRequestSigned) (out *pp.GetVerificationEmailResponse, err error) {
err = s.doClient(ctx, func(cl pp.DRPCAnyPaymentProcessingClient) error {
if out, err = cl.GetVerificationEmail(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
func (s *service) VerifyEmail(ctx context.Context, in *pp.VerifyEmailRequestSigned) (out *pp.VerifyEmailResponse, err error) {
err = s.doClient(ctx, func(cl pp.DRPCAnyPaymentProcessingClient) error {
if out, err = cl.VerifyEmail(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
func (s *service) FinalizeSubscription(ctx context.Context, in *pp.FinalizeSubscriptionRequestSigned) (out *pp.FinalizeSubscriptionResponse, err error) {
err = s.doClient(ctx, func(cl pp.DRPCAnyPaymentProcessingClient) error {
if out, err = cl.FinalizeSubscription(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
func (s *service) GetAllTiers(ctx context.Context, in *pp.GetTiersRequestSigned) (out *pp.GetTiersResponse, err error) {
err = s.doClient(ctx, func(cl pp.DRPCAnyPaymentProcessingClient) error {
if out, err = cl.GetAllTiers(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
func (s *service) IsNameValid(ctx context.Context, in *pp.IsNameValidRequest) (out *pp.IsNameValidResponse, err error) {
err = s.doClient(ctx, func(cl pp.DRPCAnyPaymentProcessingClient) error {
if out, err = cl.IsNameValid(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}
func (s *service) VerifyAppStoreReceipt(ctx context.Context, in *pp.VerifyAppStoreReceiptRequestSigned) (out *pp.VerifyAppStoreReceiptResponse, err error) {
err = s.doClient(ctx, func(cl pp.DRPCAnyPaymentProcessingClient) error {
if out, err = cl.VerifyAppStoreReceipt(ctx, in); err != nil {
return rpcerr.Unwrap(err)
}
return nil
})
return
}

View file

@ -0,0 +1,32 @@
package paymentserviceproto
import (
"errors"
"github.com/anyproto/any-sync/net/rpc/rpcerr"
)
var (
errGroup = rpcerr.ErrGroup(ErrorCodes_ErrorOffset)
ErrEthAddressEmpty = errGroup.Register(errors.New("owner eth address is empty"), uint64(ErrorCodes_EthAddressEmpty))
ErrInvalidSignature = errGroup.Register(errors.New("invalid signature"), uint64(ErrorCodes_InvalidSignature))
ErrTierWrong = errGroup.Register(errors.New("wrong tier specified"), uint64(ErrorCodes_TierWrong))
ErrTierNotFound = errGroup.Register(errors.New("requested tier not found"), uint64(ErrorCodes_TierNotFound))
ErrTierInactive = errGroup.Register(errors.New("requested tier is not active"), uint64(ErrorCodes_TierInactive))
ErrPaymentMethodWrong = errGroup.Register(errors.New("wrong payment method specified"), uint64(ErrorCodes_PaymentMethodWrong))
ErrBadAnyName = errGroup.Register(errors.New("bad any name specified"), uint64(ErrorCodes_BadAnyName))
ErrUnknown = errGroup.Register(errors.New("unknown error"), uint64(ErrorCodes_Unknown))
ErrSubsAlreadyActive = errGroup.Register(errors.New("user already has an active subscription"), uint64(ErrorCodes_SubsAlreadyActive))
ErrSubsNotFound = errGroup.Register(errors.New("no subscription for user"), uint64(ErrorCodes_SubsNotFound))
ErrSubsWrongState = errGroup.Register(errors.New("subscription is not in PendingRequiresFinalization state"), uint64(ErrorCodes_SubsWrongState))
ErrEmailWrongFormat = errGroup.Register(errors.New("wrong email format"), uint64(ErrorCodes_EmailWrongFormat))
ErrEmailAlreadyVerified = errGroup.Register(errors.New("email already verified"), uint64(ErrorCodes_EmailAlreadyVerified))
ErrEmailAlreadySent = errGroup.Register(errors.New("email verification request already sent. wait for the email or try again later"), uint64(ErrorCodes_EmailAlreadySent))
ErrEmailFailedToSend = errGroup.Register(errors.New("failed to send email"), uint64(ErrorCodes_EmailFailedToSend))
ErrEmailExpired = errGroup.Register(errors.New("email verification request expired. try getting new code"), uint64(ErrorCodes_EmailExpired))
ErrEmailWrongCode = errGroup.Register(errors.New("wrong verification code"), uint64(ErrorCodes_EmailWrongCode))
ErrAppleInvalidReceipt = errGroup.Register(errors.New("invalid AppStore receipt"), uint64(ErrorCodes_AppleInvalidReceipt))
ErrApplePurchaseRegistration = errGroup.Register(errors.New("error on purchase registration"), uint64(ErrorCodes_ApplePurchaseRegistration))
ErrAppleSubscriptionRenew = errGroup.Register(errors.New("error on subscription renew"), uint64(ErrorCodes_AppleSubscriptionRenew))
)

File diff suppressed because it is too large Load diff

View file

@ -41,7 +41,14 @@ type DRPCAnyPaymentProcessingClient interface {
DRPCConn() drpc.Conn
GetSubscriptionStatus(ctx context.Context, in *GetSubscriptionRequestSigned) (*GetSubscriptionResponse, error)
IsNameValid(ctx context.Context, in *IsNameValidRequest) (*IsNameValidResponse, error)
BuySubscription(ctx context.Context, in *BuySubscriptionRequestSigned) (*BuySubscriptionResponse, error)
FinalizeSubscription(ctx context.Context, in *FinalizeSubscriptionRequestSigned) (*FinalizeSubscriptionResponse, error)
GetSubscriptionPortalLink(ctx context.Context, in *GetSubscriptionPortalLinkRequestSigned) (*GetSubscriptionPortalLinkResponse, error)
GetVerificationEmail(ctx context.Context, in *GetVerificationEmailRequestSigned) (*GetVerificationEmailResponse, error)
VerifyEmail(ctx context.Context, in *VerifyEmailRequestSigned) (*VerifyEmailResponse, error)
GetAllTiers(ctx context.Context, in *GetTiersRequestSigned) (*GetTiersResponse, error)
VerifyAppStoreReceipt(ctx context.Context, in *VerifyAppStoreReceiptRequestSigned) (*VerifyAppStoreReceiptResponse, error)
}
type drpcAnyPaymentProcessingClient struct {
@ -63,6 +70,15 @@ func (c *drpcAnyPaymentProcessingClient) GetSubscriptionStatus(ctx context.Conte
return out, nil
}
func (c *drpcAnyPaymentProcessingClient) IsNameValid(ctx context.Context, in *IsNameValidRequest) (*IsNameValidResponse, error) {
out := new(IsNameValidResponse)
err := c.cc.Invoke(ctx, "/AnyPaymentProcessing/IsNameValid", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcAnyPaymentProcessingClient) BuySubscription(ctx context.Context, in *BuySubscriptionRequestSigned) (*BuySubscriptionResponse, error) {
out := new(BuySubscriptionResponse)
err := c.cc.Invoke(ctx, "/AnyPaymentProcessing/BuySubscription", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}, in, out)
@ -72,9 +88,70 @@ func (c *drpcAnyPaymentProcessingClient) BuySubscription(ctx context.Context, in
return out, nil
}
func (c *drpcAnyPaymentProcessingClient) FinalizeSubscription(ctx context.Context, in *FinalizeSubscriptionRequestSigned) (*FinalizeSubscriptionResponse, error) {
out := new(FinalizeSubscriptionResponse)
err := c.cc.Invoke(ctx, "/AnyPaymentProcessing/FinalizeSubscription", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcAnyPaymentProcessingClient) GetSubscriptionPortalLink(ctx context.Context, in *GetSubscriptionPortalLinkRequestSigned) (*GetSubscriptionPortalLinkResponse, error) {
out := new(GetSubscriptionPortalLinkResponse)
err := c.cc.Invoke(ctx, "/AnyPaymentProcessing/GetSubscriptionPortalLink", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcAnyPaymentProcessingClient) GetVerificationEmail(ctx context.Context, in *GetVerificationEmailRequestSigned) (*GetVerificationEmailResponse, error) {
out := new(GetVerificationEmailResponse)
err := c.cc.Invoke(ctx, "/AnyPaymentProcessing/GetVerificationEmail", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcAnyPaymentProcessingClient) VerifyEmail(ctx context.Context, in *VerifyEmailRequestSigned) (*VerifyEmailResponse, error) {
out := new(VerifyEmailResponse)
err := c.cc.Invoke(ctx, "/AnyPaymentProcessing/VerifyEmail", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcAnyPaymentProcessingClient) GetAllTiers(ctx context.Context, in *GetTiersRequestSigned) (*GetTiersResponse, error) {
out := new(GetTiersResponse)
err := c.cc.Invoke(ctx, "/AnyPaymentProcessing/GetAllTiers", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcAnyPaymentProcessingClient) VerifyAppStoreReceipt(ctx context.Context, in *VerifyAppStoreReceiptRequestSigned) (*VerifyAppStoreReceiptResponse, error) {
out := new(VerifyAppStoreReceiptResponse)
err := c.cc.Invoke(ctx, "/AnyPaymentProcessing/VerifyAppStoreReceipt", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
type DRPCAnyPaymentProcessingServer interface {
GetSubscriptionStatus(context.Context, *GetSubscriptionRequestSigned) (*GetSubscriptionResponse, error)
IsNameValid(context.Context, *IsNameValidRequest) (*IsNameValidResponse, error)
BuySubscription(context.Context, *BuySubscriptionRequestSigned) (*BuySubscriptionResponse, error)
FinalizeSubscription(context.Context, *FinalizeSubscriptionRequestSigned) (*FinalizeSubscriptionResponse, error)
GetSubscriptionPortalLink(context.Context, *GetSubscriptionPortalLinkRequestSigned) (*GetSubscriptionPortalLinkResponse, error)
GetVerificationEmail(context.Context, *GetVerificationEmailRequestSigned) (*GetVerificationEmailResponse, error)
VerifyEmail(context.Context, *VerifyEmailRequestSigned) (*VerifyEmailResponse, error)
GetAllTiers(context.Context, *GetTiersRequestSigned) (*GetTiersResponse, error)
VerifyAppStoreReceipt(context.Context, *VerifyAppStoreReceiptRequestSigned) (*VerifyAppStoreReceiptResponse, error)
}
type DRPCAnyPaymentProcessingUnimplementedServer struct{}
@ -83,13 +160,41 @@ func (s *DRPCAnyPaymentProcessingUnimplementedServer) GetSubscriptionStatus(cont
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnyPaymentProcessingUnimplementedServer) IsNameValid(context.Context, *IsNameValidRequest) (*IsNameValidResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnyPaymentProcessingUnimplementedServer) BuySubscription(context.Context, *BuySubscriptionRequestSigned) (*BuySubscriptionResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnyPaymentProcessingUnimplementedServer) FinalizeSubscription(context.Context, *FinalizeSubscriptionRequestSigned) (*FinalizeSubscriptionResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnyPaymentProcessingUnimplementedServer) GetSubscriptionPortalLink(context.Context, *GetSubscriptionPortalLinkRequestSigned) (*GetSubscriptionPortalLinkResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnyPaymentProcessingUnimplementedServer) GetVerificationEmail(context.Context, *GetVerificationEmailRequestSigned) (*GetVerificationEmailResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnyPaymentProcessingUnimplementedServer) VerifyEmail(context.Context, *VerifyEmailRequestSigned) (*VerifyEmailResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnyPaymentProcessingUnimplementedServer) GetAllTiers(context.Context, *GetTiersRequestSigned) (*GetTiersResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCAnyPaymentProcessingUnimplementedServer) VerifyAppStoreReceipt(context.Context, *VerifyAppStoreReceiptRequestSigned) (*VerifyAppStoreReceiptResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
type DRPCAnyPaymentProcessingDescription struct{}
func (DRPCAnyPaymentProcessingDescription) NumMethods() int { return 2 }
func (DRPCAnyPaymentProcessingDescription) NumMethods() int { return 9 }
func (DRPCAnyPaymentProcessingDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
switch n {
@ -103,6 +208,15 @@ func (DRPCAnyPaymentProcessingDescription) Method(n int) (string, drpc.Encoding,
)
}, DRPCAnyPaymentProcessingServer.GetSubscriptionStatus, true
case 1:
return "/AnyPaymentProcessing/IsNameValid", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnyPaymentProcessingServer).
IsNameValid(
ctx,
in1.(*IsNameValidRequest),
)
}, DRPCAnyPaymentProcessingServer.IsNameValid, true
case 2:
return "/AnyPaymentProcessing/BuySubscription", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnyPaymentProcessingServer).
@ -111,6 +225,60 @@ func (DRPCAnyPaymentProcessingDescription) Method(n int) (string, drpc.Encoding,
in1.(*BuySubscriptionRequestSigned),
)
}, DRPCAnyPaymentProcessingServer.BuySubscription, true
case 3:
return "/AnyPaymentProcessing/FinalizeSubscription", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnyPaymentProcessingServer).
FinalizeSubscription(
ctx,
in1.(*FinalizeSubscriptionRequestSigned),
)
}, DRPCAnyPaymentProcessingServer.FinalizeSubscription, true
case 4:
return "/AnyPaymentProcessing/GetSubscriptionPortalLink", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnyPaymentProcessingServer).
GetSubscriptionPortalLink(
ctx,
in1.(*GetSubscriptionPortalLinkRequestSigned),
)
}, DRPCAnyPaymentProcessingServer.GetSubscriptionPortalLink, true
case 5:
return "/AnyPaymentProcessing/GetVerificationEmail", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnyPaymentProcessingServer).
GetVerificationEmail(
ctx,
in1.(*GetVerificationEmailRequestSigned),
)
}, DRPCAnyPaymentProcessingServer.GetVerificationEmail, true
case 6:
return "/AnyPaymentProcessing/VerifyEmail", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnyPaymentProcessingServer).
VerifyEmail(
ctx,
in1.(*VerifyEmailRequestSigned),
)
}, DRPCAnyPaymentProcessingServer.VerifyEmail, true
case 7:
return "/AnyPaymentProcessing/GetAllTiers", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnyPaymentProcessingServer).
GetAllTiers(
ctx,
in1.(*GetTiersRequestSigned),
)
}, DRPCAnyPaymentProcessingServer.GetAllTiers, true
case 8:
return "/AnyPaymentProcessing/VerifyAppStoreReceipt", drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCAnyPaymentProcessingServer).
VerifyAppStoreReceipt(
ctx,
in1.(*VerifyAppStoreReceiptRequestSigned),
)
}, DRPCAnyPaymentProcessingServer.VerifyAppStoreReceipt, true
default:
return "", nil, nil, nil, false
}
@ -136,6 +304,22 @@ func (x *drpcAnyPaymentProcessing_GetSubscriptionStatusStream) SendAndClose(m *G
return x.CloseSend()
}
type DRPCAnyPaymentProcessing_IsNameValidStream interface {
drpc.Stream
SendAndClose(*IsNameValidResponse) error
}
type drpcAnyPaymentProcessing_IsNameValidStream struct {
drpc.Stream
}
func (x *drpcAnyPaymentProcessing_IsNameValidStream) SendAndClose(m *IsNameValidResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCAnyPaymentProcessing_BuySubscriptionStream interface {
drpc.Stream
SendAndClose(*BuySubscriptionResponse) error
@ -151,3 +335,99 @@ func (x *drpcAnyPaymentProcessing_BuySubscriptionStream) SendAndClose(m *BuySubs
}
return x.CloseSend()
}
type DRPCAnyPaymentProcessing_FinalizeSubscriptionStream interface {
drpc.Stream
SendAndClose(*FinalizeSubscriptionResponse) error
}
type drpcAnyPaymentProcessing_FinalizeSubscriptionStream struct {
drpc.Stream
}
func (x *drpcAnyPaymentProcessing_FinalizeSubscriptionStream) SendAndClose(m *FinalizeSubscriptionResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCAnyPaymentProcessing_GetSubscriptionPortalLinkStream interface {
drpc.Stream
SendAndClose(*GetSubscriptionPortalLinkResponse) error
}
type drpcAnyPaymentProcessing_GetSubscriptionPortalLinkStream struct {
drpc.Stream
}
func (x *drpcAnyPaymentProcessing_GetSubscriptionPortalLinkStream) SendAndClose(m *GetSubscriptionPortalLinkResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCAnyPaymentProcessing_GetVerificationEmailStream interface {
drpc.Stream
SendAndClose(*GetVerificationEmailResponse) error
}
type drpcAnyPaymentProcessing_GetVerificationEmailStream struct {
drpc.Stream
}
func (x *drpcAnyPaymentProcessing_GetVerificationEmailStream) SendAndClose(m *GetVerificationEmailResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCAnyPaymentProcessing_VerifyEmailStream interface {
drpc.Stream
SendAndClose(*VerifyEmailResponse) error
}
type drpcAnyPaymentProcessing_VerifyEmailStream struct {
drpc.Stream
}
func (x *drpcAnyPaymentProcessing_VerifyEmailStream) SendAndClose(m *VerifyEmailResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCAnyPaymentProcessing_GetAllTiersStream interface {
drpc.Stream
SendAndClose(*GetTiersResponse) error
}
type drpcAnyPaymentProcessing_GetAllTiersStream struct {
drpc.Stream
}
func (x *drpcAnyPaymentProcessing_GetAllTiersStream) SendAndClose(m *GetTiersResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCAnyPaymentProcessing_VerifyAppStoreReceiptStream interface {
drpc.Stream
SendAndClose(*VerifyAppStoreReceiptResponse) error
}
type drpcAnyPaymentProcessing_VerifyAppStoreReceiptStream struct {
drpc.Stream
}
func (x *drpcAnyPaymentProcessing_VerifyAppStoreReceiptStream) SendAndClose(m *VerifyAppStoreReceiptResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_paymentservice_paymentserviceproto_protos_paymentservice_proto{}); err != nil {
return err
}
return x.CloseSend()
}

File diff suppressed because it is too large Load diff

View file

@ -1,86 +1,101 @@
syntax = "proto3";
option go_package = "paymentservice/paymentserviceproto";
// TODO: no marshalling avail :-(
//import "google/protobuf/timestamp.proto";
import "paymentservice/paymentserviceproto/protos/paymentservice_tiers.proto";
// TODO:
// later we will have an interface to enumerate all available tiers
// it's a bad idea to list them here, because interface will be changed often
enum SubscriptionTier {
Tier_Unknown = 0;
TierUnknown = 0;
// "free" tier
TierExplorer = 1;
Tier_Friend = 1;
Tier_Supporter1Year = 2;
Tier_Patron1Year = 3;
// these can be used just for testing in debug mode
// it will still create an active subscription, but with NO features
TierBuilder1WeekTEST = 2;
TierCoCreator1WeekTEST = 3;
// these are the real tiers:
TierBuilder1Year = 4;
TierCoCreator1Year = 5;
TierBuilderPlus = 6;
TierAnytypeTeam = 7;
}
enum SubscriptionStatus {
Status_Unknown = 0;
Status_Pending = 1;
Status_Active = 2;
Status_Expired = 3;
Status_Canceled = 4;
StatusUnknown = 0;
// payment is still pending
// this will be the status until the payment is confirmed or N is elapsed and no payment is received
// in the last case the subscription will switch to Status_Unknown or Status_Active
StatusPending = 1;
StatusActive = 2;
// when buying from other side - some data is missing in the Subscription
// we need to provide additional data after the payment
// please call FinalizeSubscription to fill-in needed fields
StatusPendingRequiresFinalization = 3;
}
enum PaymentMethod {
Method_Card = 0;
Method_Crypto = 1;
Method_ApplePay = 2;
Method_GooglePay = 3;
MethodCard = 0;
MethodCrypto = 1;
MethodApplePay = 2;
MethodGooglePay = 3;
MethodAppleInapp = 4;
MethodGoogleInapp = 5;
MethodNone = 6;
}
// 1
message GetSubscriptionRequest {
// in the following format: "12D3KooWA8EXV3KjBxEU5EnsPfneLx84vMWAtTBQBeyooN82KSuS"
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
string ownerAnyID = 1;
}
message GetSubscriptionRequestSigned {
// GetSubscriptionRequest
bytes payload = 1;
// this is payload signed with payload.ownerAnyID
bytes signature = 2;
}
message GetSubscriptionResponse {
SubscriptionTier tier = 1;
// was SubscriptionTier before, changed to uint32 to allow us to use dynamic tiers
uint32 tier = 1;
SubscriptionStatus status = 2;
//TODO: use google.protobuf.Timestamp and marshall it
uint64 dateStarted = 3;
uint64 dateEnds = 4;
bool isAutoRenew = 5;
// if client has "downgraded" - he is still able to use the service until the end of the period
// (dateEnds) but then he will be on nextTier until nextTierEnds
//
// if Tier0_Unknown -> then no next tier
SubscriptionTier nextTier = 6;
uint64 nextTierEnds = 7;
PaymentMethod paymentMethod = 8;
PaymentMethod paymentMethod = 6;
string requestedAnyName = 7;
// if user verified her email OR provided it while buying a subscription, it will be here
string userEmail = 8;
bool subscribeToNewsletter = 9;
}
// 2
message BuySubscriptionRequest {
// in the following format: "12D3KooWA8EXV3KjBxEU5EnsPfneLx84vMWAtTBQBeyooN82KSuS"
string ownerAnyID = 1;
// this is the owner's ETH main EOA (External Owned Account) address
// not AccountAbstraction's SCW (Smart Contract Wallet) address!
//
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
string ownerAnyId = 1;
// this is the owner's main EOA (Externally Owned Account) address
// not AccountAbstraction's SCW (Smart Contract Wallet) address!
// this is required to reserve a name for the owner (later that is done by user)
// in the following format: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"
// this is required to reserve a name for the owner
string ownerEthAddress = 2;
SubscriptionTier requestedTier = 3;
// was SubscriptionTier before, changed to uint32 to allow us to use dynamic tiers
uint32 requestedTier = 3;
PaymentMethod paymentMethod = 4;
// if empty - then no name requested
// if non-empty - PP node will register that name on behalf of the user
string requestedAnyName = 5;
// for some payment methods we need to know the user's email
string userEmail = 6;
}
message BuySubscriptionRequestSigned {
// BuySubscriptionRequest
bytes payload = 1;
// this is payload signed with payload.ownerAnyID
bytes signature = 2;
}
@ -89,19 +104,206 @@ message BuySubscriptionResponse {
// will feature current billing ID
// stripe.com/?client_reference_id=1234
string paymentUrl = 1;
// billingID is passed via mobile client to payment platform
string billingID = 2;
}
message FinalizeSubscriptionRequest {
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
string ownerAnyId = 1;
// this is the owner's main EOA (Externally Owned Account) address
// not AccountAbstraction's SCW (Smart Contract Wallet) address!
// this is required to reserve a name for the owner (later that is done by user)
// in the following format: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"
string ownerEthAddress = 2;
// if empty - then no name requested
string requestedAnyName = 3;
}
message FinalizeSubscriptionResponse {
}
message FinalizeSubscriptionRequestSigned {
// VerifyEmailRequest
bytes payload = 1;
// this is payload signed with payload.ownerAnyID
bytes signature = 2;
}
message GetSubscriptionPortalLinkRequest {
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
string ownerAnyId = 1;
}
message GetSubscriptionPortalLinkRequestSigned {
// GetSubscriptionPortalLinkRequest
bytes payload = 1;
// this is payload signed with payload.ownerAnyID
bytes signature = 2;
}
message GetSubscriptionPortalLinkResponse {
string portalUrl = 1;
}
message GetVerificationEmailRequest {
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
string ownerAnyId = 1;
string email = 2;
bool subscribeToNewsletter = 3;
}
message GetVerificationEmailResponse {
}
message GetVerificationEmailRequestSigned {
// GetVerificationEmailRequest
bytes payload = 1;
// this is payload signed with payload.ownerAnyID
bytes signature = 2;
}
message VerifyEmailRequest {
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
string ownerAnyId = 1;
// this is the owner's main EOA (Externally Owned Account) address
// not AccountAbstraction's SCW (Smart Contract Wallet) address!
// this is required to reserve a name for the owner (later that is done by user)
// in the following format: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"
string ownerEthAddress = 2;
// code received in the email
string code = 3;
}
message VerifyEmailResponse {
bool success = 1;
}
message VerifyEmailRequestSigned {
// VerifyEmailRequest
bytes payload = 1;
// this is payload signed with payload.ownerAnyID
bytes signature = 2;
}
message IsNameValidRequest {
uint32 requestedTier = 1;
string requestedAnyName = 2;
}
message IsNameValidResponse {
Code code = 1;
string description = 2;
enum Code {
Valid = 0;
NoDotAny = 1;
TooShort = 2;
TooLong = 3;
HasInvalidChars = 4;
TierFeatureNoName = 5;
CanNotReserve = 6;
// if everything is fine - "name is already taken" check should be done in the NS
// see IsNameAvailable()
}
}
message VerifyAppStoreReceiptRequest {
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
string ownerAnyId = 1;
// receipt is a JWT-encoded information about subscription purchase
string receipt = 2;
}
message VerifyAppStoreReceiptRequestSigned {
// VerifyAppStoreReceiptRequest
bytes payload = 1;
// this is payload signed with payload.ownerAnyID
bytes signature = 2;
}
message VerifyAppStoreReceiptResponse {
}
enum ErrorCodes {
Unexpected = 0;
EthAddressEmpty = 1;
InvalidSignature = 2;
TierWrong = 3;
TierNotFound = 4;
TierInactive = 5;
PaymentMethodWrong = 6;
BadAnyName = 7;
Unknown = 8;
SubsAlreadyActive = 9;
SubsNotFound = 10;
SubsWrongState = 11;
EmailWrongFormat = 12;
EmailAlreadyVerified = 13;
EmailAlreadySent = 14;
EmailFailedToSend = 15;
EmailExpired = 16;
EmailWrongCode = 17;
AppleInvalidReceipt = 18;
ApplePurchaseRegistration = 19;
AppleSubscriptionRenew = 20;
ErrorOffset = 600;
}
// NOTICE:
// 1 - User can not ask for a payment/other links on behalf of another user (a signature is required)
// 2 - Admin can do that on behalf of any user
service AnyPaymentProcessing {
rpc GetSubscriptionStatus(GetSubscriptionRequestSigned) returns (GetSubscriptionResponse) {}
// Will save a new BillingID to DB, and return a payment link
// You can:
// a) buy a subscription
// b) TODO: upgrade your tier
// c) TODO: renew subscription
//
// WARNING:
// 1 - User can not ask for a payment link on behalf of another user (a signature is required)
// 2 - Admin can do that on behalf of a user
// Check if the requested name is valid for the requested tier
// before requesting a payment link and paying
rpc IsNameValid(IsNameValidRequest) returns (IsNameValidResponse) {}
// Save a new BillingID to DB, and return a payment link.
// You can call BuySubscription multiple times even if current payment is not processed yet
// (to get new payment link).
// If user has already an active subscription, then this will return an error.
rpc BuySubscription(BuySubscriptionRequestSigned) returns (BuySubscriptionResponse) {}
// If your subscription is in StatusPendingRequiresFinalization, then you need to call this method
rpc FinalizeSubscription(FinalizeSubscriptionRequestSigned) returns (FinalizeSubscriptionResponse) {}
// Generate a link to the portal where user can:
// a) change her billing details
// b) see payment info, invoices, etc
// c) cancel/renew the subscription
rpc GetSubscriptionPortalLink(GetSubscriptionPortalLinkRequestSigned) returns (GetSubscriptionPortalLinkResponse) {}
// Verify user's email: 1st step - get a verification link to the email
// Will fail if already verified, i.e. you can not change your email
rpc GetVerificationEmail(GetVerificationEmailRequestSigned) returns (GetVerificationEmailResponse) {}
// Enter the code from the email
// Will fail if: link was not requested, link is expired, if email is already verified
rpc VerifyEmail(VerifyEmailRequestSigned) returns (VerifyEmailResponse) {}
// Returns all available application tiers, including inactive
// 1 - this list does not depend on the current platform (iOS, Android, Desktop)
// 2 - this list can be different for different users, based on their account ID
// 3 - user can not buy stripe
// 4 - some tiers are custom ()
rpc GetAllTiers(GetTiersRequestSigned) returns (GetTiersResponse) {}
// Verify purchase in case subscription was bought via AppStore
// Incoming receipt contains all information to register purchase on Payment Node
rpc VerifyAppStoreReceipt(VerifyAppStoreReceiptRequestSigned) returns (VerifyAppStoreReceiptResponse) {}
}

View file

@ -0,0 +1,81 @@
syntax = "proto3";
option go_package = "paymentservice/paymentserviceproto";
enum PeriodType {
PeriodTypeUnknown = 0;
PeriodTypeUnlimited = 1;
PeriodTypeDays = 2;
PeriodTypeWeeks = 3;
PeriodTypeMonths = 4;
PeriodTypeYears = 5;
}
message Feature {
string description = 1;
}
message GetTiersRequest {
// in the following format: "A5k2d9sFZw84yisTxRnz2bPRd1YPfVfhxqymZ6yESprFTG65"
// you can get it with Account().SignKey.GetPublic().Account()
string ownerAnyId = 1;
string locale = 2;
}
message GetTiersRequestSigned {
// GetTiersRequest struct
bytes payload = 1;
// this is payload signed with payload.ownerAnyID
bytes signature = 2;
}
message TierData {
// this is a unique ID of the tier
// you should hardcode this in your app and provide icon, graphics, etc for each tier
// (even for old/historical/inactive/hidden tiers)
uint32 id = 1;
// localazied name of the tier
string name = 2;
// just a short technical description
// you don't have to use it, you can use your own UI-friendly texts
string description = 3;
// can you buy it (ON ALL PLATFORMS, without clarification)?
bool isActive = 4;
// is this tier for debugging only?
bool isTest = 5;
// hidden tiers are only visible once user got them
bool isHiddenTier = 6;
// how long is the period of the subscription
PeriodType periodType = 7;
// i.e. "5 days" or "3 years"
uint32 periodValue = 8;
// this one is a price we use ONLY on Stripe platform
uint32 priceStripeUsdCents = 9;
// number of ANY NS names that this tier includes
// (not counted as a "feature" and not in the features list)
uint32 anyNamesCountIncluded = 10;
// somename.any - len of 8
uint32 anyNameMinLength = 11;
// each tier has a set of features
repeated Feature features = 12;
// green, blue, red, purple or custom color in string format #ff00ff
string colorStr = 13;
// Stripe platform-specific data:
string stripeProductId = 14;
string stripeManageUrl = 15;
// iOS platform-specific data:
string iosProductId = 16;
string iosManageUrl = 17;
// Android platform-specific data:
string androidProductId = 18;
string androidManageUrl = 19;
}
message GetTiersResponse {
// list of all available tiers
repeated TierData tiers = 1;
}

View file

@ -0,0 +1,22 @@
package anymock
import "go.uber.org/mock/gomock"
type MockComp interface {
Name() *gomock.Call
Init(x any) *gomock.Call
}
type MockCompRunnable interface {
Run(x any) *gomock.Call
Close(x any) *gomock.Call
}
func ExpectComp(c MockComp, name string) {
c.Name().Return(name).AnyTimes()
c.Init(gomock.Any()).AnyTimes()
if cr, ok := c.(MockCompRunnable); ok {
cr.Run(gomock.Any()).AnyTimes()
cr.Close(gomock.Any()).AnyTimes()
}
}

View file

@ -7,11 +7,11 @@ import (
"fmt"
"github.com/anyproto/go-slip10"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcutil/hdkeychain"
"github.com/tyler-smith/go-bip39"
hdwallet "github.com/miguelmota/go-ethereum-hdwallet"
"github.com/ethereum/go-ethereum/common"
"github.com/anyproto/any-sync/util/ethereum/accounts"
)
var (
@ -40,6 +40,9 @@ type DerivationResult struct {
OldAccountKey PrivKey
MasterNode slip10.Node
// Anytype uses ED25519
// Ethereum and Bitcoin use ECDSA secp256k1 elliptic curves
//
// this key is used to sign ethereum transactions to use Any Naming Service
// same mnemonic/seed phrase is used as for AnyType identity
// m/44'/60'/0'/0/index
@ -134,7 +137,7 @@ func (m Mnemonic) DeriveKeys(index uint32) (res DerivationResult, err error) {
res.OldAccountKey = oldRes.MasterKey
// now derive ethereum key
_, pk, err := m.ethereumKeyFromMnemonic(index, defaultEthereumDerivation)
pk, err := m.ethereumKeyFromMnemonic(index, defaultEthereumDerivation)
if err != nil {
return
}
@ -164,28 +167,49 @@ func genKey(node slip10.Node) (key PrivKey, err error) {
return
}
func (m Mnemonic) ethereumKeyFromMnemonic(index uint32, path string) (addr common.Address, pk *ecdsa.PrivateKey, err error) {
wallet, err := hdwallet.NewFromMnemonic(string(m))
func derivePrivateKey(masterKey *hdkeychain.ExtendedKey, path accounts.DerivationPath) (*ecdsa.PrivateKey, error) {
var err error
key := masterKey
for _, n := range path {
key, err = key.DeriveNonStandard(n)
if err != nil {
return nil, err
}
}
privateKey, err := key.ECPrivKey()
privateKeyECDSA := privateKey.ToECDSA()
if err != nil {
return common.Address{}, nil, err
return nil, err
}
return privateKeyECDSA, nil
}
func (m Mnemonic) ethereumKeyFromMnemonic(index uint32, path string) (pk *ecdsa.PrivateKey, err error) {
seed, err := m.Seed()
if err != nil {
return
}
masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
if err != nil {
return nil, err
}
// m/44'/60'/0'/0/0 for first account
// m/44'/60'/0'/0/1 for second account, etc
fullPath := fmt.Sprintf("%s/%d", path, index)
p := hdwallet.MustParseDerivationPath(fullPath)
account, err := wallet.Derive(p, false)
p, err := accounts.ParseDerivationPath(fullPath)
if err != nil {
return common.Address{}, nil, err
panic(err)
}
addr = account.Address
pk, err = wallet.PrivateKey(account)
pk, err = derivePrivateKey(masterKey, p)
if err != nil {
return common.Address{}, nil, err
return nil, err
}
return addr, pk, nil
return pk, nil
}

View file

@ -2,17 +2,49 @@ package crypto
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"encoding/hex"
"fmt"
"strings"
"testing"
"github.com/anyproto/go-slip10"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/sha3"
)
func Keccak256(data []byte) []byte {
hash := sha3.NewLegacyKeccak256()
hash.Write(data)
return hash.Sum(nil)
}
func PublicKeyToAddress(pub *ecdsa.PublicKey) string {
// Serialize the public key to a byte slice
pubBytes := elliptic.Marshal(pub.Curve, pub.X, pub.Y)
// Compute the Keccak256 hash of the public key (excluding the first byte)
hash := Keccak256(pubBytes[1:])
// Take the last 20 bytes of the hash as the address
address := hash[12:]
return fmt.Sprintf("0x%x", address)
}
func PrivateKeyToBytes(priv *ecdsa.PrivateKey) []byte {
return priv.D.Bytes()
}
// Encode encodes b as a hex string with 0x prefix.
func Encode(b []byte) string {
enc := make([]byte, len(b)*2+2)
copy(enc, "0x")
hex.Encode(enc[2:], b)
return string(enc)
}
func TestMnemonic(t *testing.T) {
phrase, err := NewMnemonicGenerator().WithWordCount(12)
require.NoError(t, err)
@ -55,33 +87,53 @@ func TestMnemonic(t *testing.T) {
publicKey := res.EthereumIdentity.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
require.Equal(t, true, ok)
ethAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
require.Equal(t, common.HexToAddress("0xC49926C4124cEe1cbA0Ea94Ea31a6c12318df947"), ethAddress)
// convert publicKeyECDSA to address
ethAddress := PublicKeyToAddress(publicKeyECDSA)
shouldBe := strings.ToLower("0xC49926C4124cEe1cbA0Ea94Ea31a6c12318df947")
require.Equal(t, shouldBe, ethAddress)
}
func TestMnemonic_ethereumKeyFromMnemonic(t *testing.T) {
var badPphrase Mnemonic = "tag volcano"
_, _, err := badPphrase.ethereumKeyFromMnemonic(0, defaultEthereumDerivation)
_, err := badPphrase.ethereumKeyFromMnemonic(0, defaultEthereumDerivation)
require.Error(t, err)
// good
var phrase Mnemonic = "tag volcano eight thank tide danger coast health above argue embrace heavy"
addr, pk, err := phrase.ethereumKeyFromMnemonic(0, defaultEthereumDerivation)
pk, err := phrase.ethereumKeyFromMnemonic(0, defaultEthereumDerivation)
require.NoError(t, err)
require.Equal(t, common.HexToAddress("0xC49926C4124cEe1cbA0Ea94Ea31a6c12318df947"), addr)
// check address
publicKey := pk.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
require.Equal(t, true, ok)
// convert publicKeyECDSA to address
ethAddress := PublicKeyToAddress(publicKeyECDSA)
shouldBe := strings.ToLower("0xC49926C4124cEe1cbA0Ea94Ea31a6c12318df947")
require.Equal(t, shouldBe, ethAddress)
// what wallet.PrivateKeyHex(account) does
bytes := crypto.FromECDSA(pk)
pkStr := hexutil.Encode(bytes)[2:]
bytes := PrivateKeyToBytes(pk)
pkStr := Encode(bytes)[2:]
require.Equal(t, "63e21d10fd50155dbba0e7d3f7431a400b84b4c2ac1ee38872f82448fe3ecfb9", pkStr)
addr, pk, err = phrase.ethereumKeyFromMnemonic(1, defaultEthereumDerivation)
pk, err = phrase.ethereumKeyFromMnemonic(1, defaultEthereumDerivation)
require.NoError(t, err)
require.Equal(t, common.HexToAddress("0x8230645aC28A4EdD1b0B53E7Cd8019744E9dD559"), addr)
bytes = crypto.FromECDSA(pk)
pkStr = hexutil.Encode(bytes)[2:]
// check address
publicKey = pk.Public()
publicKeyECDSA, ok = publicKey.(*ecdsa.PublicKey)
require.Equal(t, true, ok)
// convert publicKeyECDSA to address
ethAddress = PublicKeyToAddress(publicKeyECDSA)
shouldBe = strings.ToLower("0x8230645aC28A4EdD1b0B53E7Cd8019744E9dD559")
require.Equal(t, shouldBe, ethAddress)
bytes = PrivateKeyToBytes(pk)
pkStr = Encode(bytes)[2:]
require.Equal(t, "b31048b0aa87649bdb9016c0ee28c788ddfc45e52cd71cc0da08c47cb4390ae7", pkStr)
}

28
util/debug/stack.go Normal file
View file

@ -0,0 +1,28 @@
package debug
import (
"bytes"
"compress/gzip"
"encoding/base64"
"runtime"
)
func StackCompact(allGoroutines bool) string {
var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
_, _ = gz.Write(Stack(allGoroutines))
_ = gz.Close()
return base64.StdEncoding.EncodeToString(buf.Bytes())
}
func Stack(allGoroutines bool) []byte {
buf := make([]byte, 1024)
for {
n := runtime.Stack(buf, allGoroutines)
if n < len(buf) {
return buf[:n]
}
buf = make([]byte, 2*len(buf))
}
}

38
util/debug/stack_test.go Normal file
View file

@ -0,0 +1,38 @@
package debug
import (
"bytes"
"compress/gzip"
"encoding/base64"
"strings"
"testing"
"github.com/stretchr/testify/require"
)
func TestStack(t *testing.T) {
stack := Stack(true)
require.True(t, strings.Contains(string(stack), "main.main"))
}
func TestStackCompact(t *testing.T) {
stack := StackCompact(true)
decoded, err := base64.StdEncoding.DecodeString(string(stack))
require.NoError(t, err)
rd, err := gzip.NewReader(bytes.NewReader(decoded))
require.NoError(t, err)
var (
buf = make([]byte, 1024)
res []byte
)
for {
n, err := rd.Read(buf)
if n > 0 {
res = append(res, buf[:n]...)
}
if err != nil {
break
}
}
require.True(t, strings.Contains(string(res), "main.main"))
}

View file

@ -0,0 +1,112 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package accounts
import (
"errors"
"fmt"
"math"
"math/big"
"strings"
)
// DefaultRootDerivationPath is the root path to which custom derivation endpoints
// are appended. As such, the first account will be at m/44'/60'/0'/0, the second
// at m/44'/60'/0'/1, etc.
var DefaultRootDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0}
// DefaultBaseDerivationPath is the base path from which custom derivation endpoints
// are incremented. As such, the first account will be at m/44'/60'/0'/0/0, the second
// at m/44'/60'/0'/0/1, etc.
var DefaultBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0}
// DerivationPath represents the computer friendly version of a hierarchical
// deterministic wallet account derivation path.
//
// The BIP-32 spec https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
// defines derivation paths to be of the form:
//
// m / purpose' / coin_type' / account' / change / address_index
//
// The BIP-44 spec https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
// defines that the `purpose` be 44' (or 0x8000002C) for crypto currencies, and
// SLIP-44 https://github.com/satoshilabs/slips/blob/master/slip-0044.md assigns
// the `coin_type` 60' (or 0x8000003C) to Ethereum.
//
// The root path for Ethereum is m/44'/60'/0'/0 according to the specification
// from https://github.com/ethereum/EIPs/issues/84, albeit it's not set in stone
// yet whether accounts should increment the last component or the children of
// that. We will go with the simpler approach of incrementing the last component.
type DerivationPath []uint32
// ParseDerivationPath converts a user specified derivation path string to the
// internal binary representation.
//
// Full derivation paths need to start with the `m/` prefix, relative derivation
// paths (which will get appended to the default root path) must not have prefixes
// in front of the first element. Whitespace is ignored.
func ParseDerivationPath(path string) (DerivationPath, error) {
var result DerivationPath
// Handle absolute or relative paths
components := strings.Split(path, "/")
switch {
case len(components) == 0:
return nil, errors.New("empty derivation path")
case strings.TrimSpace(components[0]) == "":
return nil, errors.New("ambiguous path: use 'm/' prefix for absolute paths, or no leading '/' for relative ones")
case strings.TrimSpace(components[0]) == "m":
components = components[1:]
default:
result = append(result, DefaultRootDerivationPath...)
}
// All remaining components are relative, append one by one
if len(components) == 0 {
return nil, errors.New("empty derivation path") // Empty relative paths
}
for _, component := range components {
// Ignore any user added whitespace
component = strings.TrimSpace(component)
var value uint32
// Handle hardened paths
if strings.HasSuffix(component, "'") {
value = 0x80000000
component = strings.TrimSpace(strings.TrimSuffix(component, "'"))
}
// Handle the non hardened component
bigval, ok := new(big.Int).SetString(component, 0)
if !ok {
return nil, fmt.Errorf("invalid component: %s", component)
}
max := math.MaxUint32 - value
if bigval.Sign() < 0 || bigval.Cmp(big.NewInt(int64(max))) > 0 {
if value == 0 {
return nil, fmt.Errorf("component %v out of allowed range [0, %d]", bigval, max)
}
return nil, fmt.Errorf("component %v out of allowed hardened range [0, %d]", bigval, max)
}
value += uint32(bigval.Uint64())
// Append and repeat
result = append(result, value)
}
return result, nil
}