mirror of
https://github.com/anyproto/anytype-heart.git
synced 2025-06-10 01:51:07 +09:00
Remove foundAccounts and ipfs lite
This commit is contained in:
parent
a4c69329ae
commit
fe56f4e697
5 changed files with 92 additions and 392 deletions
132
core/account.go
132
core/account.go
|
@ -10,6 +10,7 @@ import (
|
|||
"fmt"
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
|
@ -28,7 +29,6 @@ import (
|
|||
"github.com/anytypeio/go-anytype-middleware/core/anytype"
|
||||
"github.com/anytypeio/go-anytype-middleware/core/anytype/config"
|
||||
"github.com/anytypeio/go-anytype-middleware/core/block"
|
||||
importer "github.com/anytypeio/go-anytype-middleware/core/block/import"
|
||||
"github.com/anytypeio/go-anytype-middleware/core/configfetcher"
|
||||
"github.com/anytypeio/go-anytype-middleware/core/filestorage"
|
||||
walletComp "github.com/anytypeio/go-anytype-middleware/core/wallet"
|
||||
|
@ -47,6 +47,7 @@ import (
|
|||
|
||||
// we cannot check the constant error from badger because they hardcoded it there
|
||||
const errSubstringMultipleAnytypeInstance = "Cannot acquire directory lock"
|
||||
const profileFile = "profile"
|
||||
|
||||
type AlphaInviteRequest struct {
|
||||
Code string `json:"code"`
|
||||
|
@ -321,7 +322,6 @@ func (mw *Middleware) AccountCreate(cctx context.Context, req *pb.RpcAccountCrea
|
|||
return response(newAcc, pb.RpcAccountCreateResponseError_ACCOUNT_CREATED_BUT_FAILED_TO_SET_NAME, err)
|
||||
}
|
||||
|
||||
mw.foundAccounts = append(mw.foundAccounts, newAcc)
|
||||
return response(newAcc, pb.RpcAccountCreateResponseError_NULL, nil)
|
||||
}
|
||||
|
||||
|
@ -347,7 +347,7 @@ func (mw *Middleware) AccountRecover(cctx context.Context, _ *pb.RpcAccountRecov
|
|||
return response(pb.RpcAccountRecoverResponseError_NEED_TO_RECOVER_WALLET_FIRST, nil)
|
||||
}
|
||||
|
||||
account, err := mw.getDerivedAccountForMnemonic()
|
||||
account, err := core.WalletAccountAt(mw.mnemonic, 0)
|
||||
if err != nil {
|
||||
return response(pb.RpcAccountRecoverResponseError_BAD_INPUT, err)
|
||||
}
|
||||
|
@ -663,8 +663,6 @@ func (mw *Middleware) AccountRemoveLocalData() error {
|
|||
|
||||
func (mw *Middleware) AccountRecoverFromLegacyExport(cctx context.Context,
|
||||
req *pb.RpcAccountRecoverFromLegacyExportRequest) *pb.RpcAccountRecoverFromLegacyExportResponse {
|
||||
ctx := mw.newContext(cctx)
|
||||
|
||||
response := func(address string, code pb.RpcAccountRecoverFromLegacyExportResponseErrorCode, err error) *pb.RpcAccountRecoverFromLegacyExportResponse {
|
||||
m := &pb.RpcAccountRecoverFromLegacyExportResponse{AccountId: address, Error: &pb.RpcAccountRecoverFromLegacyExportResponseError{Code: code}}
|
||||
if err != nil {
|
||||
|
@ -672,60 +670,91 @@ func (mw *Middleware) AccountRecoverFromLegacyExport(cctx context.Context,
|
|||
}
|
||||
return m
|
||||
}
|
||||
profile, err := importer.ImportUserProfile(ctx, req)
|
||||
profile, err := getUserProfile(req)
|
||||
if err != nil {
|
||||
return response("", pb.RpcAccountRecoverFromLegacyExportResponseError_UNKNOWN_ERROR, err)
|
||||
}
|
||||
err = mw.createAccountFromLegacyExport(profile, req)
|
||||
code, err := mw.createAccountFromLegacyExport(profile, req)
|
||||
if err != nil {
|
||||
return response("", pb.RpcAccountRecoverFromLegacyExportResponseError_UNKNOWN_ERROR, err)
|
||||
return response("", code, err)
|
||||
}
|
||||
|
||||
return response(profile.Address, pb.RpcAccountRecoverFromLegacyExportResponseError_NULL, nil)
|
||||
}
|
||||
|
||||
func (mw *Middleware) createAccountFromLegacyExport(profile *pb.Profile, req *pb.RpcAccountRecoverFromLegacyExportRequest) error {
|
||||
mw.m.Lock()
|
||||
|
||||
defer mw.m.Unlock()
|
||||
if err := mw.stop(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mw.rootPath = req.RootPath
|
||||
mw.foundAccounts = nil
|
||||
|
||||
err := os.MkdirAll(mw.rootPath, 0700)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = mw.setMnemonic(profile.Mnemonic)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mw.accountSearchCancel()
|
||||
|
||||
func getUserProfile(req *pb.RpcAccountRecoverFromLegacyExportRequest) (*pb.Profile, error) {
|
||||
archive, err := zip.OpenReader(req.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
oldCfg, err := extractConfig(archive)
|
||||
defer archive.Close()
|
||||
|
||||
f, err := archive.Open(profileFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to extract config: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg := anytype.BootstrapConfig(true, os.Getenv("ANYTYPE_STAGING") == "1", false)
|
||||
cfg.LegacyFileStorePath = oldCfg.LegacyFileStorePath
|
||||
data, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var profile pb.Profile
|
||||
|
||||
err = profile.Unmarshal(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &profile, nil
|
||||
}
|
||||
|
||||
func (mw *Middleware) createAccountFromLegacyExport(profile *pb.Profile, req *pb.RpcAccountRecoverFromLegacyExportRequest) (pb.RpcAccountRecoverFromLegacyExportResponseErrorCode, error) {
|
||||
mw.m.Lock()
|
||||
defer mw.m.Unlock()
|
||||
err := mw.stop()
|
||||
if err != nil {
|
||||
return pb.RpcAccountRecoverFromLegacyExportResponseError_UNKNOWN_ERROR, err
|
||||
}
|
||||
|
||||
account, err := core.WalletAccountAt(mw.mnemonic, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
return pb.RpcAccountRecoverFromLegacyExportResponseError_UNKNOWN_ERROR, err
|
||||
}
|
||||
address := account.GetPublic().Account()
|
||||
if address == "" || profile.Address != address {
|
||||
return pb.RpcAccountRecoverFromLegacyExportResponseError_DIFFERENT_ACCOUNT, fmt.Errorf("backup was made from different account")
|
||||
}
|
||||
|
||||
// todo: parse config.json from legacy export
|
||||
mw.rootPath = req.RootPath
|
||||
err = os.MkdirAll(mw.rootPath, 0700)
|
||||
if err != nil {
|
||||
return pb.RpcAccountRecoverFromLegacyExportResponseError_UNKNOWN_ERROR, err
|
||||
}
|
||||
mw.accountSearchCancel()
|
||||
if _, statErr := os.Stat(filepath.Join(mw.rootPath, address)); os.IsNotExist(statErr) && account != nil {
|
||||
if walletErr := core.WalletInitRepo(mw.rootPath, account); walletErr != nil {
|
||||
return pb.RpcAccountRecoverFromLegacyExportResponseError_UNKNOWN_ERROR, walletErr
|
||||
}
|
||||
}
|
||||
cfg, err := mw.getBootstrapConfig(err, req)
|
||||
if err != nil {
|
||||
return pb.RpcAccountRecoverFromLegacyExportResponseError_UNKNOWN_ERROR, err
|
||||
}
|
||||
|
||||
newAcc := &model.Account{Id: address}
|
||||
err = mw.startApp(cfg, account, err)
|
||||
if err != nil {
|
||||
return pb.RpcAccountRecoverFromLegacyExportResponseError_UNKNOWN_ERROR, err
|
||||
}
|
||||
|
||||
err = mw.setDetails(profile, err)
|
||||
if err != nil {
|
||||
return pb.RpcAccountRecoverFromLegacyExportResponseError_UNKNOWN_ERROR, err
|
||||
}
|
||||
|
||||
return pb.RpcAccountRecoverFromLegacyExportResponseError_NULL, nil
|
||||
}
|
||||
|
||||
func (mw *Middleware) startApp(cfg *config.Config, account crypto.PrivKey, err error) error {
|
||||
comps := []app.Component{
|
||||
cfg,
|
||||
anytype.BootstrapWallet(mw.rootPath, account),
|
||||
|
@ -736,18 +765,31 @@ func (mw *Middleware) createAccountFromLegacyExport(profile *pb.Profile, req *pb
|
|||
if mw.app, err = anytype.StartNewApp(ctxWithValue, comps...); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
newAcc.Name = profile.Name
|
||||
func (mw *Middleware) getBootstrapConfig(err error, req *pb.RpcAccountRecoverFromLegacyExportRequest) (*config.Config, error) {
|
||||
archive, err := zip.OpenReader(req.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oldCfg, err := extractConfig(archive)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract config: %w", err)
|
||||
}
|
||||
|
||||
cfg := anytype.BootstrapConfig(true, os.Getenv("ANYTYPE_STAGING") == "1", false)
|
||||
cfg.LegacyFileStorePath = oldCfg.LegacyFileStorePath
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (mw *Middleware) setDetails(profile *pb.Profile, err error) error {
|
||||
details := []*pb.RpcObjectSetDetailsDetail{{Key: "name", Value: pbtypes.String(profile.Name)}}
|
||||
newAcc.Avatar = &model.AccountAvatar{Avatar: &model.AccountAvatarAvatarOfImage{
|
||||
Image: &model.BlockContentFile{Hash: profile.Avatar},
|
||||
}}
|
||||
details = append(details, &pb.RpcObjectSetDetailsDetail{
|
||||
Key: "iconImage",
|
||||
Value: pbtypes.String(profile.Avatar),
|
||||
})
|
||||
|
||||
newAcc.Info = mw.getInfo()
|
||||
bs := mw.app.MustComponent(block.CName).(*block.Service)
|
||||
coreService := mw.app.MustComponent(core.CName).(core.Service)
|
||||
if err = bs.SetDetails(nil, pb.RpcObjectSetDetailsRequest{
|
||||
|
@ -756,8 +798,6 @@ func (mw *Middleware) createAccountFromLegacyExport(profile *pb.Profile, req *pb
|
|||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mw.foundAccounts = append(mw.foundAccounts, newAcc)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -780,10 +820,6 @@ func extractConfig(archive *zip.ReadCloser) (*config.Config, error) {
|
|||
return nil, fmt.Errorf("config.json not found in archive")
|
||||
}
|
||||
|
||||
func (mw *Middleware) getDerivedAccountForMnemonic() (crypto.PrivKey, error) {
|
||||
return crypto.Mnemonic(mw.mnemonic).DeriveEd25519Key(0)
|
||||
}
|
||||
|
||||
func (mw *Middleware) isAccountExistsOnDisk(account string) bool {
|
||||
if _, err := os.Stat(filepath.Join(mw.rootPath, account)); err == nil {
|
||||
return true
|
||||
|
|
14
core/core.go
14
core/core.go
|
@ -3,12 +3,12 @@ package core
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/anytypeio/go-anytype-middleware/space"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
|
||||
"github.com/anytypeio/any-sync/app"
|
||||
|
||||
"github.com/anytypeio/go-anytype-middleware/core/block"
|
||||
"github.com/anytypeio/go-anytype-middleware/core/block/collection"
|
||||
"github.com/anytypeio/go-anytype-middleware/core/event"
|
||||
|
@ -17,7 +17,7 @@ import (
|
|||
"github.com/anytypeio/go-anytype-middleware/pb"
|
||||
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
|
||||
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
|
||||
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
|
||||
"github.com/anytypeio/go-anytype-middleware/space"
|
||||
)
|
||||
|
||||
var log = logging.Logger("anytype-mw-api")
|
||||
|
@ -33,10 +33,7 @@ type Middleware struct {
|
|||
// memoized private key derived from mnemonic
|
||||
privateKey []byte
|
||||
accountSearchCancel context.CancelFunc
|
||||
|
||||
foundAccounts []*model.Account // found local&remote account for the current mnemonic
|
||||
|
||||
EventSender event.Sender
|
||||
EventSender event.Sender
|
||||
|
||||
sessions session.Service
|
||||
app *app.App
|
||||
|
@ -168,3 +165,8 @@ func (mw *Middleware) OnPanic(v interface{}) {
|
|||
os.Stderr.Write(stack)
|
||||
log.With("stack", stack).Errorf("panic recovered: %v", v)
|
||||
}
|
||||
|
||||
func init() {
|
||||
// let leave it here so it will work in all types of distribution and tests
|
||||
logging.SetVersion(app.GitSummary)
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ func (mw *Middleware) WalletCreate(cctx context.Context, req *pb.RpcWalletCreate
|
|||
defer mw.m.Unlock()
|
||||
|
||||
mw.rootPath = req.RootPath
|
||||
mw.foundAccounts = nil
|
||||
|
||||
err := os.MkdirAll(mw.rootPath, 0700)
|
||||
if err != nil {
|
||||
|
@ -97,8 +96,6 @@ func (mw *Middleware) WalletRecover(cctx context.Context, req *pb.RpcWalletRecov
|
|||
return response(pb.RpcWalletRecoverResponseError_UNKNOWN_ERROR, err)
|
||||
}
|
||||
mw.rootPath = req.RootPath
|
||||
mw.foundAccounts = nil
|
||||
|
||||
return response(pb.RpcWalletRecoverResponseError_NULL, nil)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
package ipfslite
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
HostAddr ma.Multiaddr
|
||||
Offline bool
|
||||
PrivKey crypto.PrivKey // takes precedence over PrivKeyFromPath
|
||||
PrivateNetSecret string
|
||||
BootstrapNodes []peer.AddrInfo
|
||||
RelayNodes []peer.AddrInfo
|
||||
SwarmLowWater int
|
||||
SwarmHighWater int
|
||||
}
|
|
@ -1,317 +0,0 @@
|
|||
package ipfslite
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/ipfs/go-ipns"
|
||||
"github.com/libp2p/go-libp2p"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
ipfslite "github.com/hsanjuan/ipfs-lite"
|
||||
"github.com/ipfs/go-cid"
|
||||
ds "github.com/ipfs/go-datastore"
|
||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
uio "github.com/ipfs/go-unixfs/io"
|
||||
dht "github.com/libp2p/go-libp2p-kad-dht"
|
||||
dualdht "github.com/libp2p/go-libp2p-kad-dht/dual"
|
||||
record "github.com/libp2p/go-libp2p-record"
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/pnet"
|
||||
"github.com/libp2p/go-libp2p/core/routing"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/autorelay"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds"
|
||||
connmgr "github.com/libp2p/go-libp2p/p2p/net/connmgr"
|
||||
libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls"
|
||||
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
|
||||
"github.com/libp2p/go-libp2p/p2p/transport/websocket"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
madns "github.com/multiformats/go-multiaddr-dns"
|
||||
"github.com/textileio/go-threads/util"
|
||||
|
||||
app "github.com/anytypeio/any-sync/app"
|
||||
"github.com/anytypeio/go-anytype-middleware/core/anytype/config"
|
||||
"github.com/anytypeio/go-anytype-middleware/core/wallet"
|
||||
"github.com/anytypeio/go-anytype-middleware/pkg/lib/datastore"
|
||||
"github.com/anytypeio/go-anytype-middleware/pkg/lib/ipfs"
|
||||
"github.com/anytypeio/go-anytype-middleware/pkg/lib/logging"
|
||||
"github.com/anytypeio/go-anytype-middleware/pkg/lib/net/resolver"
|
||||
"github.com/anytypeio/go-anytype-middleware/pkg/lib/util/nocloserds"
|
||||
)
|
||||
|
||||
const CName = "ipfs"
|
||||
|
||||
var log = logging.Logger("anytype-core-litenet")
|
||||
|
||||
type liteNet struct {
|
||||
cfg *Config
|
||||
*ipfslite.Peer
|
||||
ds datastore.Datastore
|
||||
host host.Host
|
||||
dht *dualdht.DHT
|
||||
|
||||
peerStoreCtxCancel context.CancelFunc
|
||||
|
||||
bootstrapSucceed bool
|
||||
bootstrapFinished chan struct{}
|
||||
}
|
||||
|
||||
func New() ipfs.Node {
|
||||
return &liteNet{}
|
||||
}
|
||||
|
||||
func (ln *liteNet) getConfig(a *app.App) (*Config, error) {
|
||||
appCfg := a.MustComponent(config.CName).(*config.Config)
|
||||
wl := a.MustComponent(wallet.CName).(wallet.Wallet)
|
||||
|
||||
keypair, err := wl.GetDevicePrivkey()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get device keypair: %v", err)
|
||||
}
|
||||
|
||||
hostAddrStr := appCfg.HostAddr
|
||||
if hostAddrStr == "" {
|
||||
hostAddrStr = "/ip4/0.0.0.0/tcp/0"
|
||||
}
|
||||
hostAddr, err := ma.NewMultiaddr(hostAddrStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bootstrapNodes, err := util.ParseBootstrapPeers(appCfg.BootstrapNodes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
relayNodes, err := util.ParseBootstrapPeers(appCfg.RelayNodes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg := Config{
|
||||
HostAddr: hostAddr,
|
||||
PrivKey: keypair,
|
||||
PrivateNetSecret: appCfg.PrivateNetworkSecret,
|
||||
BootstrapNodes: bootstrapNodes,
|
||||
RelayNodes: relayNodes,
|
||||
SwarmLowWater: appCfg.SwarmLowWater,
|
||||
SwarmHighWater: appCfg.SwarmHighWater,
|
||||
Offline: appCfg.Offline,
|
||||
}
|
||||
|
||||
if cfg.PrivateNetSecret == "" {
|
||||
// todo: remove this temporarily error in order to be able to connect to public IPFS
|
||||
return nil, fmt.Errorf("private network secret is nil")
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
func (ln *liteNet) Init(a *app.App) (err error) {
|
||||
ln.ds = a.MustComponent(datastore.CName).(datastore.Datastore)
|
||||
ln.bootstrapFinished = make(chan struct{})
|
||||
|
||||
res, err := madns.NewResolver(
|
||||
madns.WithDefaultResolver(resolver.NewResolverWithTTL(time.Minute * 30)),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
madns.DefaultResolver = res
|
||||
|
||||
ln.cfg, err = ln.getConfig(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func newDHT(ctx context.Context, h host.Host, ds ds.Batching) (*dualdht.DHT, error) {
|
||||
dhtOpts := []dualdht.Option{
|
||||
dualdht.DHTOption(dht.NamespacedValidator("pk", record.PublicKeyValidator{})),
|
||||
dualdht.DHTOption(dht.NamespacedValidator("ipns", ipns.Validator{KeyBook: h.Peerstore()})),
|
||||
dualdht.DHTOption(dht.Concurrency(10)),
|
||||
dualdht.DHTOption(dht.Mode(dht.ModeAuto)),
|
||||
}
|
||||
if ds != nil {
|
||||
dhtOpts = append(dhtOpts, dualdht.DHTOption(dht.Datastore(ds)))
|
||||
}
|
||||
|
||||
return dualdht.New(ctx, h, dhtOpts...)
|
||||
}
|
||||
|
||||
func withForceReachability(reachability network.Reachability) libp2p.Option {
|
||||
return func(cfg *libp2p.Config) error {
|
||||
cfg.AutoNATConfig.ForceReachability = &reachability
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func setupLibP2PNode(ctx context.Context, cfg *Config, blockDS, peerDS ds.Batching) (host.Host, *dualdht.DHT, error) {
|
||||
var ddht *dualdht.DHT
|
||||
var err error
|
||||
|
||||
pstore, err := pstoreds.NewPeerstore(ctx, peerDS, pstoreds.DefaultOpts())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
r := bytes.NewReader([]byte(cfg.PrivateNetSecret))
|
||||
privateNetworkKey, err := pnet.DecodeV1PSK(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
transports := libp2p.ChainOptions(
|
||||
libp2p.NoTransports,
|
||||
libp2p.Transport(tcp.NewTCPTransport, tcp.WithConnectionTimeout(time.Second*10)),
|
||||
libp2p.Transport(websocket.New),
|
||||
)
|
||||
|
||||
cnmgr, err := connmgr.NewConnManager(cfg.SwarmLowWater, cfg.SwarmHighWater, connmgr.WithGracePeriod(time.Minute))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
finalOpts := []libp2p.Option{
|
||||
libp2p.Identity(cfg.PrivKey),
|
||||
libp2p.ListenAddrs(cfg.HostAddr),
|
||||
libp2p.PrivateNetwork(privateNetworkKey),
|
||||
transports,
|
||||
libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) {
|
||||
ddht, err = newDHT(ctx, h, blockDS)
|
||||
return ddht, err
|
||||
}),
|
||||
withForceReachability(network.ReachabilityPrivate), // most of the clients are behind NAT,
|
||||
// so start with that assumption and then in case it wrong we will switch to public
|
||||
libp2p.ConnectionManager(cnmgr),
|
||||
libp2p.Peerstore(pstore),
|
||||
libp2p.Security(libp2ptls.ID, libp2ptls.New),
|
||||
libp2p.EnableAutoRelay(autorelay.WithStaticRelays(cfg.RelayNodes)), // if our network state
|
||||
// changes we will try to connect to one of the relay specified below. In case we are under
|
||||
// NAT we will announce our addresses through these nodes
|
||||
}
|
||||
|
||||
h, err := libp2p.New(
|
||||
finalOpts...,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return h, ddht, err
|
||||
}
|
||||
|
||||
func (ln *liteNet) Run(_ context.Context) error {
|
||||
var ctx context.Context
|
||||
ctx, ln.peerStoreCtxCancel = context.WithCancel(context.Background())
|
||||
|
||||
peerDS, err := ln.ds.PeerstoreDS()
|
||||
if err != nil {
|
||||
return fmt.Errorf("peerDS: %s", err.Error())
|
||||
}
|
||||
blockDS, err := ln.ds.BlockstoreDS()
|
||||
if err != nil {
|
||||
return fmt.Errorf("blockDS: %s", err.Error())
|
||||
}
|
||||
|
||||
peerDS = nocloserds.NewBatch(peerDS)
|
||||
blockDS = nocloserds.NewBatch(blockDS)
|
||||
|
||||
ln.host, ln.dht, err = setupLibP2PNode(ctx, ln.cfg, blockDS, peerDS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ln.Peer, err = ipfslite.New(ctx, blockDS, nil, ln.host, ln.dht, &ipfslite.Config{Offline: ln.cfg.Offline})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
ln.Bootstrap(ln.cfg.BootstrapNodes)
|
||||
for _, p := range ln.cfg.BootstrapNodes {
|
||||
if ln.host.Network().Connectedness(p.ID) == network.Connected {
|
||||
ln.bootstrapSucceed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
log.Infof("bootstrap finished. succeed = %v", ln.bootstrapSucceed)
|
||||
|
||||
close(ln.bootstrapFinished)
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ln *liteNet) Name() (name string) {
|
||||
return CName
|
||||
}
|
||||
|
||||
func (ln *liteNet) WaitBootstrap() bool {
|
||||
<-ln.bootstrapFinished
|
||||
return ln.bootstrapSucceed
|
||||
}
|
||||
|
||||
func (ln *liteNet) GetHost() host.Host {
|
||||
return ln.host
|
||||
}
|
||||
|
||||
func (ln *liteNet) Bootstrap(addrs []peer.AddrInfo) {
|
||||
// todo refactor: provide a way to check if bootstrap was finished or/and succesfull
|
||||
ln.Peer.Bootstrap(addrs)
|
||||
}
|
||||
|
||||
func (ln *liteNet) Close(ctx context.Context) (err error) {
|
||||
if ln.peerStoreCtxCancel != nil {
|
||||
ln.peerStoreCtxCancel()
|
||||
}
|
||||
|
||||
if ln.dht != nil {
|
||||
err = ln.dht.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if ln.host != nil {
|
||||
err = ln.host.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *liteNet) Session(ctx context.Context) ipld.NodeGetter {
|
||||
return i.Peer.Session(ctx)
|
||||
}
|
||||
|
||||
func (i *liteNet) AddFile(ctx context.Context, r io.Reader, params *ipfs.AddParams) (ipld.Node, error) {
|
||||
if params == nil {
|
||||
return i.Peer.AddFile(ctx, r, nil)
|
||||
}
|
||||
|
||||
ipfsLiteParams := ipfslite.AddParams(*params)
|
||||
return i.Peer.AddFile(ctx, r, &ipfsLiteParams)
|
||||
}
|
||||
|
||||
func (i *liteNet) GetFile(ctx context.Context, c cid.Cid) (uio.ReadSeekCloser, error) {
|
||||
return i.Peer.GetFile(ctx, c)
|
||||
}
|
||||
|
||||
func (i *liteNet) BlockStore() blockstore.Blockstore {
|
||||
return i.Peer.BlockStore()
|
||||
}
|
||||
|
||||
func (i *liteNet) HasBlock(c cid.Cid) (bool, error) {
|
||||
return i.Peer.HasBlock(context.Background(), c)
|
||||
}
|
||||
|
||||
func (i *liteNet) Remove(ctx context.Context, c cid.Cid) error {
|
||||
return i.Peer.Remove(ctx, c)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue