refactor: use a dependency injection/IoC pattern based off uber fx
This commit is contained in:
parent
384557de0c
commit
59a73e4266
2
go.mod
2
go.mod
|
@ -15,6 +15,7 @@ require (
|
||||||
github.com/vmihailenco/msgpack/v5 v5.4.1
|
github.com/vmihailenco/msgpack/v5 v5.4.1
|
||||||
go.etcd.io/bbolt v1.3.8
|
go.etcd.io/bbolt v1.3.8
|
||||||
go.sia.tech/jape v0.11.1
|
go.sia.tech/jape v0.11.1
|
||||||
|
go.uber.org/fx v1.20.1
|
||||||
go.uber.org/zap v1.26.0
|
go.uber.org/zap v1.26.0
|
||||||
nhooyr.io/websocket v1.7.1
|
nhooyr.io/websocket v1.7.1
|
||||||
)
|
)
|
||||||
|
@ -26,6 +27,7 @@ require (
|
||||||
github.com/multiformats/go-base36 v0.1.0 // indirect
|
github.com/multiformats/go-base36 v0.1.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
|
go.uber.org/dig v1.17.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
|
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
|
||||||
golang.org/x/net v0.17.0 // indirect
|
golang.org/x/net v0.17.0 // indirect
|
||||||
|
|
64
node/node.go
64
node/node.go
|
@ -17,7 +17,6 @@ import (
|
||||||
"github.com/vmihailenco/msgpack/v5"
|
"github.com/vmihailenco/msgpack/v5"
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,11 +25,9 @@ const cacheBucketName = "object-cache"
|
||||||
type Node struct {
|
type Node struct {
|
||||||
nodeConfig *config.NodeConfig
|
nodeConfig *config.NodeConfig
|
||||||
metadataCache structs.Map
|
metadataCache structs.Map
|
||||||
started bool
|
|
||||||
hashQueryRoutingTable structs.Map
|
hashQueryRoutingTable structs.Map
|
||||||
services service.Services
|
services service.Services
|
||||||
httpClient *resty.Client
|
httpClient *resty.Client
|
||||||
connections sync.WaitGroup
|
|
||||||
providerStore storage.ProviderStore
|
providerStore storage.ProviderStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,24 +39,21 @@ func (n *Node) Services() service.Services {
|
||||||
return n.services
|
return n.services
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNode(config *config.NodeConfig) *Node {
|
func NewNode(config *config.NodeConfig, services service.Services) *Node {
|
||||||
n := &Node{
|
return &Node{
|
||||||
nodeConfig: config,
|
nodeConfig: config,
|
||||||
metadataCache: structs.NewMap(),
|
metadataCache: structs.NewMap(),
|
||||||
started: false,
|
|
||||||
hashQueryRoutingTable: structs.NewMap(),
|
hashQueryRoutingTable: structs.NewMap(),
|
||||||
httpClient: resty.New(),
|
httpClient: resty.New(),
|
||||||
|
services: services, // Services are passed in, not created here
|
||||||
}
|
}
|
||||||
n.services = NewServices(service.NewP2P(n), service.NewRegistry(n), service.NewHTTP(n))
|
|
||||||
|
|
||||||
return n
|
|
||||||
}
|
}
|
||||||
func (n *Node) HashQueryRoutingTable() structs.Map {
|
func (n *Node) HashQueryRoutingTable() structs.Map {
|
||||||
return n.hashQueryRoutingTable
|
return n.hashQueryRoutingTable
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) IsStarted() bool {
|
func (n *Node) IsStarted() bool {
|
||||||
return n.started
|
return n.services.IsStarted()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Config() *config.NodeConfig {
|
func (n *Node) Config() *config.NodeConfig {
|
||||||
|
@ -81,8 +75,8 @@ func (n *Node) Db() *bolt.DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Start() error {
|
func (n *Node) Start() error {
|
||||||
protocol.Init()
|
protocol.RegisterProtocols()
|
||||||
signed.Init()
|
signed.RegisterSignedProtocols()
|
||||||
err :=
|
err :=
|
||||||
utils.CreateBucket(cacheBucketName, n.Db())
|
utils.CreateBucket(cacheBucketName, n.Db())
|
||||||
|
|
||||||
|
@ -90,22 +84,13 @@ func (n *Node) Start() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
n.started = true
|
return n.services.Start()
|
||||||
|
|
||||||
for _, svc := range n.services.All() {
|
|
||||||
err := svc.Init()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = svc.Start()
|
func (n *Node) Stop() error {
|
||||||
if err != nil {
|
return n.services.Stop()
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n.started = true
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) GetCachedStorageLocations(hash *encoding.Multihash, kinds []types.StorageLocationType) (map[string]storage.StorageLocation, error) {
|
func (n *Node) GetCachedStorageLocations(hash *encoding.Multihash, kinds []types.StorageLocationType) (map[string]storage.StorageLocation, error) {
|
||||||
locations := make(map[string]storage.StorageLocation)
|
locations := make(map[string]storage.StorageLocation)
|
||||||
|
|
||||||
|
@ -325,11 +310,7 @@ func (n *Node) GetMetadataByCID(cid *encoding.CID) (md metadata.Metadata, err er
|
||||||
return md, nil
|
return md, nil
|
||||||
}
|
}
|
||||||
func (n *Node) WaitOnConnectedPeers() {
|
func (n *Node) WaitOnConnectedPeers() {
|
||||||
n.connections.Wait()
|
n.services.P2P().WaitOnConnectedPeers()
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) ConnectionTracker() *sync.WaitGroup {
|
|
||||||
return &n.connections
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SetProviderStore(store storage.ProviderStore) {
|
func (n *Node) SetProviderStore(store storage.ProviderStore) {
|
||||||
|
@ -339,3 +320,26 @@ func (n *Node) SetProviderStore(store storage.ProviderStore) {
|
||||||
func (n *Node) ProviderStore() storage.ProviderStore {
|
func (n *Node) ProviderStore() storage.ProviderStore {
|
||||||
return n.providerStore
|
return n.providerStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DefaultNode(config *config.NodeConfig) *Node {
|
||||||
|
params := service.ServiceParams{
|
||||||
|
Logger: config.Logger,
|
||||||
|
Config: config,
|
||||||
|
Db: config.DB,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize services first
|
||||||
|
p2pService := service.NewP2P(params)
|
||||||
|
registryService := service.NewRegistry(params)
|
||||||
|
httpService := service.NewHTTP(params)
|
||||||
|
|
||||||
|
// Aggregate services
|
||||||
|
services := NewServices(ServicesParams{
|
||||||
|
P2P: p2pService,
|
||||||
|
Registry: registryService,
|
||||||
|
HTTP: httpService,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Now create the node with the services
|
||||||
|
return NewNode(config, services)
|
||||||
|
}
|
||||||
|
|
|
@ -8,10 +8,17 @@ var (
|
||||||
_ service.Services = (*ServicesImpl)(nil)
|
_ service.Services = (*ServicesImpl)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ServicesParams struct {
|
||||||
|
P2P *service.P2PService
|
||||||
|
Registry *service.RegistryService
|
||||||
|
HTTP *service.HTTPService
|
||||||
|
}
|
||||||
|
|
||||||
type ServicesImpl struct {
|
type ServicesImpl struct {
|
||||||
p2p *service.P2PService
|
p2p *service.P2PService
|
||||||
registry *service.RegistryService
|
registry *service.RegistryService
|
||||||
http *service.HTTPService
|
http *service.HTTPService
|
||||||
|
started bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServicesImpl) HTTP() *service.HTTPService {
|
func (s *ServicesImpl) HTTP() *service.HTTPService {
|
||||||
|
@ -31,14 +38,50 @@ func (s *ServicesImpl) Registry() *service.RegistryService {
|
||||||
return s.registry
|
return s.registry
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServices(p2p *service.P2PService, registry *service.RegistryService, http *service.HTTPService) service.Services {
|
func NewServices(params ServicesParams) service.Services {
|
||||||
return &ServicesImpl{
|
sc := &ServicesImpl{
|
||||||
p2p: p2p,
|
p2p: params.P2P,
|
||||||
registry: registry,
|
registry: params.Registry,
|
||||||
http: http,
|
http: params.HTTP,
|
||||||
|
started: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, svc := range sc.All() {
|
||||||
|
svc.SetServices(sc)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServicesImpl) P2P() *service.P2PService {
|
func (s *ServicesImpl) P2P() *service.P2PService {
|
||||||
return s.p2p
|
return s.p2p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ServicesImpl) IsStarted() bool {
|
||||||
|
return s.started
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServicesImpl) Start() error {
|
||||||
|
for _, svc := range s.All() {
|
||||||
|
err := svc.Start()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.started = true
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (s *ServicesImpl) Stop() error {
|
||||||
|
for _, svc := range s.All() {
|
||||||
|
err := svc.Stop()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.started = false
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ var (
|
||||||
messageTypes map[int]func() base.IncomingMessage
|
messageTypes map[int]func() base.IncomingMessage
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func RegisterProtocols() {
|
||||||
messageTypes = make(map[int]func() base.IncomingMessage)
|
messageTypes = make(map[int]func() base.IncomingMessage)
|
||||||
|
|
||||||
// Register factory functions instead of instances
|
// Register factory functions instead of instances
|
||||||
|
|
|
@ -22,7 +22,7 @@ var (
|
||||||
messageTypes map[int]func() IncomingMessageSigned
|
messageTypes map[int]func() IncomingMessageSigned
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func RegisterSignedProtocols() {
|
||||||
messageTypes = make(map[int]func() IncomingMessageSigned)
|
messageTypes = make(map[int]func() IncomingMessageSigned)
|
||||||
|
|
||||||
RegisterMessageType(int(types.ProtocolMethodHandshakeDone), func() IncomingMessageSigned {
|
RegisterMessageType(int(types.ProtocolMethodHandshakeDone), func() IncomingMessageSigned {
|
||||||
|
|
|
@ -3,8 +3,8 @@ package signed
|
||||||
import (
|
import (
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"errors"
|
"errors"
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/config"
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
||||||
_node "git.lumeweb.com/LumeWeb/libs5-go/node"
|
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/protocol/base"
|
"git.lumeweb.com/LumeWeb/libs5-go/protocol/base"
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
||||||
"github.com/vmihailenco/msgpack/v5"
|
"github.com/vmihailenco/msgpack/v5"
|
||||||
|
@ -171,7 +171,7 @@ func (s *SignedMessage) EncodeMsgpack(enc *msgpack.Encoder) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (s *SignedMessage) Sign(node *_node.Node) error {
|
func (s *SignedMessage) Sign(cfg *config.NodeConfig) error {
|
||||||
if s.nodeId == nil {
|
if s.nodeId == nil {
|
||||||
panic("nodeId is nil")
|
panic("nodeId is nil")
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ func (s *SignedMessage) Sign(node *_node.Node) error {
|
||||||
panic("message is nil")
|
panic("message is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.signature = ed25519.Sign(node.Config().KeyPair.ExtractBytes(), s.message)
|
s.signature = ed25519.Sign(cfg.KeyPair.ExtractBytes(), s.message)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package service
|
||||||
import (
|
import (
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/build"
|
"git.lumeweb.com/LumeWeb/libs5-go/build"
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/net"
|
"git.lumeweb.com/LumeWeb/libs5-go/net"
|
||||||
_node "git.lumeweb.com/LumeWeb/libs5-go/node"
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
"go.sia.tech/jape"
|
"go.sia.tech/jape"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -23,12 +22,16 @@ type P2PNodeResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type HTTPService struct {
|
type HTTPService struct {
|
||||||
node *_node.Node
|
ServiceBase
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTP(node *_node.Node) *HTTPService {
|
func NewHTTP(params ServiceParams) *HTTPService {
|
||||||
return &HTTPService{
|
return &HTTPService{
|
||||||
node: node,
|
ServiceBase: ServiceBase{
|
||||||
|
logger: params.Logger,
|
||||||
|
config: params.Config,
|
||||||
|
db: params.Db,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,10 +49,6 @@ func (h *HTTPService) GetHttpRouter(inject map[string]jape.Handler) *httprouter.
|
||||||
return jape.Mux(routes)
|
return jape.Mux(routes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HTTPService) Node() *_node.Node {
|
|
||||||
return h.node
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *HTTPService) Start() error {
|
func (h *HTTPService) Start() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -68,7 +67,7 @@ func (h *HTTPService) versionHandler(ctx jape.Context) {
|
||||||
func (h *HTTPService) p2pHandler(ctx jape.Context) {
|
func (h *HTTPService) p2pHandler(ctx jape.Context) {
|
||||||
c, err := websocket.Accept(ctx.ResponseWriter, ctx.Request, nil)
|
c, err := websocket.Accept(ctx.ResponseWriter, ctx.Request, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.node.Logger().Error("error accepting websocket connection", zap.Error(err))
|
h.logger.Error("error accepting websocket connection", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,33 +77,33 @@ func (h *HTTPService) p2pHandler(ctx jape.Context) {
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.node.Logger().Error("error creating transport peer", zap.Error(err))
|
h.logger.Error("error creating transport peer", zap.Error(err))
|
||||||
err := c.Close(websocket.StatusInternalError, "the sky is falling")
|
err := c.Close(websocket.StatusInternalError, "the sky is falling")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.node.Logger().Error("error closing websocket connection", zap.Error(err))
|
h.logger.Error("error closing websocket connection", zap.Error(err))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
h.Node().ConnectionTracker().Add(1)
|
h.services.P2P().ConnectionTracker().Add(1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
err := h.node.Services().P2P().OnNewPeer(peer, false)
|
err := h.services.P2P().OnNewPeer(peer, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.node.Logger().Error("error handling new peer", zap.Error(err))
|
h.logger.Error("error handling new peer", zap.Error(err))
|
||||||
}
|
}
|
||||||
h.node.ConnectionTracker().Done()
|
h.services.P2P().ConnectionTracker().Done()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HTTPService) p2pNodesHandler(ctx jape.Context) {
|
func (h *HTTPService) p2pNodesHandler(ctx jape.Context) {
|
||||||
localId, err := h.node.Services().P2P().NodeId().ToString()
|
localId, err := h.services.P2P().NodeId().ToString()
|
||||||
|
|
||||||
if ctx.Check("error getting local node id", err) != nil {
|
if ctx.Check("error getting local node id", err) != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uris := h.node.Services().P2P().SelfConnectionUris()
|
uris := h.services.P2P().SelfConnectionUris()
|
||||||
|
|
||||||
nodeList := make([]P2PNodeResponse, len(uris))
|
nodeList := make([]P2PNodeResponse, len(uris))
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/ed25519"
|
"git.lumeweb.com/LumeWeb/libs5-go/ed25519"
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/net"
|
"git.lumeweb.com/LumeWeb/libs5-go/net"
|
||||||
_node "git.lumeweb.com/LumeWeb/libs5-go/node"
|
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/protocol"
|
"git.lumeweb.com/LumeWeb/libs5-go/protocol"
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/protocol/base"
|
"git.lumeweb.com/LumeWeb/libs5-go/protocol/base"
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/protocol/signed"
|
"git.lumeweb.com/LumeWeb/libs5-go/protocol/signed"
|
||||||
|
@ -36,12 +35,10 @@ var (
|
||||||
const nodeBucketName = "nodes"
|
const nodeBucketName = "nodes"
|
||||||
|
|
||||||
type P2PService struct {
|
type P2PService struct {
|
||||||
logger *zap.Logger
|
|
||||||
nodeKeyPair *ed25519.KeyPairEd25519
|
nodeKeyPair *ed25519.KeyPairEd25519
|
||||||
localNodeID *encoding.NodeId
|
localNodeID *encoding.NodeId
|
||||||
networkID string
|
networkID string
|
||||||
nodesBucket *bolt.Bucket
|
nodesBucket *bolt.Bucket
|
||||||
node *_node.Node
|
|
||||||
inited bool
|
inited bool
|
||||||
reconnectDelay structs.Map
|
reconnectDelay structs.Map
|
||||||
peers structs.Map
|
peers structs.Map
|
||||||
|
@ -52,19 +49,19 @@ type P2PService struct {
|
||||||
incomingIPBlocklist structs.Map
|
incomingIPBlocklist structs.Map
|
||||||
outgoingPeerFailures structs.Map
|
outgoingPeerFailures structs.Map
|
||||||
maxOutgoingPeerFailures uint
|
maxOutgoingPeerFailures uint
|
||||||
|
connections sync.WaitGroup
|
||||||
|
ServiceBase
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewP2P(node *_node.Node) *P2PService {
|
func NewP2P(params ServiceParams) *P2PService {
|
||||||
uri, err := url.Parse(fmt.Sprintf("wss://%s:%d/s5/p2p", node.Config().HTTP.API.Domain, node.Config().HTTP.API.Port))
|
uri, err := url.Parse(fmt.Sprintf("wss://%s:%d/s5/p2p", params.Config.HTTP.API.Domain, params.Config.HTTP.API.Port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
node.Logger().Fatal("failed to HTTP API URL Config", zap.Error(err))
|
params.Logger.Fatal("failed to parse HTTP API URL", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
service := &P2PService{
|
service := &P2PService{
|
||||||
logger: node.Logger(),
|
nodeKeyPair: params.Config.KeyPair,
|
||||||
nodeKeyPair: node.Config().KeyPair,
|
networkID: params.Config.P2P.Network,
|
||||||
networkID: node.Config().P2P.Network,
|
|
||||||
node: node,
|
|
||||||
inited: false,
|
inited: false,
|
||||||
reconnectDelay: structs.NewMap(),
|
reconnectDelay: structs.NewMap(),
|
||||||
peers: structs.NewMap(),
|
peers: structs.NewMap(),
|
||||||
|
@ -74,7 +71,12 @@ func NewP2P(node *_node.Node) *P2PService {
|
||||||
incomingPeerBlockList: structs.NewMap(),
|
incomingPeerBlockList: structs.NewMap(),
|
||||||
incomingIPBlocklist: structs.NewMap(),
|
incomingIPBlocklist: structs.NewMap(),
|
||||||
outgoingPeerFailures: structs.NewMap(),
|
outgoingPeerFailures: structs.NewMap(),
|
||||||
maxOutgoingPeerFailures: node.Config().P2P.MaxOutgoingPeerFailures,
|
maxOutgoingPeerFailures: params.Config.P2P.MaxOutgoingPeerFailures,
|
||||||
|
ServiceBase: ServiceBase{
|
||||||
|
logger: params.Logger,
|
||||||
|
config: params.Config,
|
||||||
|
db: params.Db,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return service
|
return service
|
||||||
|
@ -84,16 +86,12 @@ func (p *P2PService) SelfConnectionUris() []*url.URL {
|
||||||
return p.selfConnectionUris
|
return p.selfConnectionUris
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *P2PService) Node() *_node.Node {
|
|
||||||
return p.node
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *P2PService) Peers() structs.Map {
|
func (p *P2PService) Peers() structs.Map {
|
||||||
return p.peers
|
return p.peers
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *P2PService) Start() error {
|
func (p *P2PService) Start() error {
|
||||||
config := p.Node().Config()
|
config := p.config
|
||||||
if len(config.P2P.Peers.Initial) > 0 {
|
if len(config.P2P.Peers.Initial) > 0 {
|
||||||
initialPeers := config.P2P.Peers.Initial
|
initialPeers := config.P2P.Peers.Initial
|
||||||
|
|
||||||
|
@ -117,7 +115,7 @@ func (p *P2PService) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *P2PService) Stop() error {
|
func (p *P2PService) Stop() error {
|
||||||
panic("implement me")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *P2PService) Init() error {
|
func (p *P2PService) Init() error {
|
||||||
|
@ -126,7 +124,7 @@ func (p *P2PService) Init() error {
|
||||||
}
|
}
|
||||||
p.localNodeID = encoding.NewNodeId(p.nodeKeyPair.PublicKey())
|
p.localNodeID = encoding.NewNodeId(p.nodeKeyPair.PublicKey())
|
||||||
|
|
||||||
err := utils.CreateBucket(nodeBucketName, p.Node().Db())
|
err := utils.CreateBucket(nodeBucketName, p.db)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -137,7 +135,7 @@ func (p *P2PService) Init() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (p *P2PService) ConnectToNode(connectionUris []*url.URL, retried bool, fromPeer net.Peer) error {
|
func (p *P2PService) ConnectToNode(connectionUris []*url.URL, retried bool, fromPeer net.Peer) error {
|
||||||
if !p.Node().IsStarted() {
|
if !p.services.IsStarted() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +320,7 @@ func (p *P2PService) ConnectToNode(connectionUris []*url.URL, retried bool, from
|
||||||
|
|
||||||
peer.SetId(id)
|
peer.SetId(id)
|
||||||
|
|
||||||
p.Node().ConnectionTracker().Add(1)
|
p.services.P2P().ConnectionTracker().Add(1)
|
||||||
|
|
||||||
peerId, err := peer.Id().ToString()
|
peerId, err := peer.Id().ToString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -335,7 +333,7 @@ func (p *P2PService) ConnectToNode(connectionUris []*url.URL, retried bool, from
|
||||||
if err != nil && !peer.Abuser() {
|
if err != nil && !peer.Abuser() {
|
||||||
p.logger.Error("peer error", zap.Error(err))
|
p.logger.Error("peer error", zap.Error(err))
|
||||||
}
|
}
|
||||||
p.Node().ConnectionTracker().Done()
|
p.services.P2P().ConnectionTracker().Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -443,7 +441,6 @@ func (p *P2PService) OnNewPeerListen(peer net.Peer, verifyId bool) {
|
||||||
Original: message,
|
Original: message,
|
||||||
Data: reader.Data,
|
Data: reader.Data,
|
||||||
Ctx: context.Background(),
|
Ctx: context.Background(),
|
||||||
Node: p.node,
|
|
||||||
Peer: peer,
|
Peer: peer,
|
||||||
VerifyId: verifyId,
|
VerifyId: verifyId,
|
||||||
}
|
}
|
||||||
|
@ -473,7 +470,7 @@ func (p *P2PService) OnNewPeerListen(peer net.Peer, verifyId bool) {
|
||||||
func (p *P2PService) readNodeVotes(nodeId *encoding.NodeId) (NodeVotes, error) {
|
func (p *P2PService) readNodeVotes(nodeId *encoding.NodeId) (NodeVotes, error) {
|
||||||
var value []byte
|
var value []byte
|
||||||
var found bool
|
var found bool
|
||||||
err := p.node.Db().View(func(tx *bolt.Tx) error {
|
err := p.db.View(func(tx *bolt.Tx) error {
|
||||||
b := tx.Bucket([]byte(nodeBucketName))
|
b := tx.Bucket([]byte(nodeBucketName))
|
||||||
if b == nil {
|
if b == nil {
|
||||||
return fmt.Errorf("Bucket %s not found", nodeBucketName)
|
return fmt.Errorf("Bucket %s not found", nodeBucketName)
|
||||||
|
@ -509,7 +506,7 @@ func (p *P2PService) saveNodeVotes(nodeId *encoding.NodeId, votes NodeVotes) err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a transaction to save the data
|
// Use a transaction to save the data
|
||||||
err = p.node.Db().Update(func(tx *bolt.Tx) error {
|
err = p.db.Update(func(tx *bolt.Tx) error {
|
||||||
// Get or create the bucket
|
// Get or create the bucket
|
||||||
b := tx.Bucket([]byte(nodeBucketName))
|
b := tx.Bucket([]byte(nodeBucketName))
|
||||||
|
|
||||||
|
@ -557,7 +554,7 @@ func (p *P2PService) SignMessageSimple(message []byte) ([]byte, error) {
|
||||||
signedMessage := signed.NewSignedMessageRequest(message)
|
signedMessage := signed.NewSignedMessageRequest(message)
|
||||||
signedMessage.SetNodeId(p.localNodeID)
|
signedMessage.SetNodeId(p.localNodeID)
|
||||||
|
|
||||||
err := signedMessage.Sign(p.Node())
|
err := signedMessage.Sign(p.config)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -615,7 +612,7 @@ func (p *P2PService) SendHashRequest(hash *encoding.Multihash, kinds []types.Sto
|
||||||
for _, peer := range p.peers.Values() {
|
for _, peer := range p.peers.Values() {
|
||||||
peerValue, ok := peer.(net.Peer)
|
peerValue, ok := peer.(net.Peer)
|
||||||
if !ok {
|
if !ok {
|
||||||
p.node.Logger().Error("failed to cast peer to net.Peer")
|
p.logger.Error("failed to cast peer to net.Peer")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = peerValue.SendMessage(message)
|
err = peerValue.SendMessage(message)
|
||||||
|
@ -706,3 +703,11 @@ func (p *P2PService) PrepareProvideMessage(hash *encoding.Multihash, location st
|
||||||
// Return the final byte slice.
|
// Return the final byte slice.
|
||||||
return finalList
|
return finalList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *P2PService) WaitOnConnectedPeers() {
|
||||||
|
p.connections.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *P2PService) ConnectionTracker() *sync.WaitGroup {
|
||||||
|
return &p.connections
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/net"
|
"git.lumeweb.com/LumeWeb/libs5-go/net"
|
||||||
_node "git.lumeweb.com/LumeWeb/libs5-go/node"
|
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/protocol"
|
"git.lumeweb.com/LumeWeb/libs5-go/protocol"
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/structs"
|
"git.lumeweb.com/LumeWeb/libs5-go/structs"
|
||||||
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
||||||
|
@ -23,14 +22,9 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type RegistryService struct {
|
type RegistryService struct {
|
||||||
node *_node.Node
|
|
||||||
logger *zap.Logger
|
|
||||||
streams structs.Map
|
streams structs.Map
|
||||||
subs structs.Map
|
subs structs.Map
|
||||||
}
|
ServiceBase
|
||||||
|
|
||||||
func (r *RegistryService) Node() *_node.Node {
|
|
||||||
return r.node
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RegistryService) Start() error {
|
func (r *RegistryService) Start() error {
|
||||||
|
@ -42,15 +36,18 @@ func (r *RegistryService) Stop() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RegistryService) Init() error {
|
func (r *RegistryService) Init() error {
|
||||||
return utils.CreateBucket(registryBucketName, r.node.Db())
|
return utils.CreateBucket(registryBucketName, r.db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegistry(node *_node.Node) *RegistryService {
|
func NewRegistry(params ServiceParams) *RegistryService {
|
||||||
return &RegistryService{
|
return &RegistryService{
|
||||||
node: node,
|
|
||||||
logger: node.Logger(),
|
|
||||||
streams: structs.NewMap(),
|
streams: structs.NewMap(),
|
||||||
subs: structs.NewMap(),
|
subs: structs.NewMap(),
|
||||||
|
ServiceBase: ServiceBase{
|
||||||
|
logger: params.Logger,
|
||||||
|
config: params.Config,
|
||||||
|
db: params.Db,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (r *RegistryService) Set(sre protocol.SignedRegistryEntry, trusted bool, receivedFrom net.Peer) error {
|
func (r *RegistryService) Set(sre protocol.SignedRegistryEntry, trusted bool, receivedFrom net.Peer) error {
|
||||||
|
@ -120,7 +117,7 @@ func (r *RegistryService) Set(sre protocol.SignedRegistryEntry, trusted bool, re
|
||||||
go event.Emit("fire", sre)
|
go event.Emit("fire", sre)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = r.node.Db().Update(func(txn *bbolt.Tx) error {
|
err = r.db.Update(func(txn *bbolt.Tx) error {
|
||||||
bucket := txn.Bucket([]byte(registryBucketName))
|
bucket := txn.Bucket([]byte(registryBucketName))
|
||||||
err := bucket.Put(sre.PK(), protocol.MarshalSignedRegistryEntry(sre))
|
err := bucket.Put(sre.PK(), protocol.MarshalSignedRegistryEntry(sre))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -153,7 +150,7 @@ func (r *RegistryService) BroadcastEntry(sre protocol.SignedRegistryEntry, recei
|
||||||
r.logger.Debug("[registry] broadcastEntry", zap.String("pk", hashString), zap.Uint64("revision", sre.Revision()), zap.String("receivedFrom", pid))
|
r.logger.Debug("[registry] broadcastEntry", zap.String("pk", hashString), zap.Uint64("revision", sre.Revision()), zap.String("receivedFrom", pid))
|
||||||
updateMessage := protocol.MarshalSignedRegistryEntry(sre)
|
updateMessage := protocol.MarshalSignedRegistryEntry(sre)
|
||||||
|
|
||||||
for _, p := range r.node.Services().P2P().Peers().Values() {
|
for _, p := range r.services.P2P().Peers().Values() {
|
||||||
peer, ok := p.(net.Peer)
|
peer, ok := p.(net.Peer)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
|
@ -182,7 +179,7 @@ func (r *RegistryService) SendRegistryRequest(pk []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over peers and send the request
|
// Iterate over peers and send the request
|
||||||
for _, peerVal := range r.node.Services().P2P().Peers().Values() {
|
for _, peerVal := range r.services.P2P().Peers().Values() {
|
||||||
peer, ok := peerVal.(net.Peer)
|
peer, ok := peerVal.(net.Peer)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
|
@ -295,7 +292,7 @@ func (r *RegistryService) Listen(pk []byte, cb func(sre protocol.SignedRegistryE
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RegistryService) getFromDB(pk []byte) (sre protocol.SignedRegistryEntry, err error) {
|
func (r *RegistryService) getFromDB(pk []byte) (sre protocol.SignedRegistryEntry, err error) {
|
||||||
err = r.node.Db().View(func(txn *bbolt.Tx) error {
|
err = r.db.View(func(txn *bbolt.Tx) error {
|
||||||
bucket := txn.Bucket([]byte(registryBucketName))
|
bucket := txn.Bucket([]byte(registryBucketName))
|
||||||
val := bucket.Get(pk)
|
val := bucket.Get(pk)
|
||||||
if val != nil {
|
if val != nil {
|
||||||
|
|
|
@ -1,16 +1,39 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import "git.lumeweb.com/LumeWeb/libs5-go/node"
|
import (
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/config"
|
||||||
|
bolt "go.etcd.io/bbolt"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
Node() *node.Node
|
|
||||||
Start() error
|
Start() error
|
||||||
Stop() error
|
Stop() error
|
||||||
Init() error
|
Init() error
|
||||||
|
SetServices(services Services)
|
||||||
}
|
}
|
||||||
type Services interface {
|
type Services interface {
|
||||||
P2P() *P2PService
|
P2P() *P2PService
|
||||||
Registry() *RegistryService
|
Registry() *RegistryService
|
||||||
HTTP() *HTTPService
|
HTTP() *HTTPService
|
||||||
All() []Service
|
All() []Service
|
||||||
|
IsStarted() bool
|
||||||
|
Start() error
|
||||||
|
Stop() error
|
||||||
|
}
|
||||||
|
type ServiceParams struct {
|
||||||
|
Logger *zap.Logger
|
||||||
|
Config *config.NodeConfig
|
||||||
|
Db *bolt.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceBase struct {
|
||||||
|
logger *zap.Logger
|
||||||
|
config *config.NodeConfig
|
||||||
|
db *bolt.DB
|
||||||
|
services Services
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceBase) SetServices(services Services) {
|
||||||
|
s.services = services
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue