Files
indra/pkg/engine/node/node.go
2023-06-19 17:07:54 +01:00

124 lines
2.9 KiB
Go

package node
import (
"fmt"
"github.com/indra-labs/indra/pkg/crypto"
"github.com/indra-labs/indra/pkg/crypto/nonce"
"github.com/indra-labs/indra/pkg/engine/payments"
"github.com/indra-labs/indra/pkg/engine/services"
"github.com/indra-labs/indra/pkg/engine/tpt"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"github.com/indra-labs/indra/pkg/util/slice"
"net/netip"
"sync"
)
const (
// PaymentChanBuffers is the default number of buffers used in a payment channel.
PaymentChanBuffers = 8
)
var (
log = log2.GetLogger()
fails = log.E.Chk
)
// Node is a representation of a messaging counterparty.
type Node struct {
ID nonce.ID
sync.Mutex
AddrPort *netip.AddrPort
Identity *crypto.Keys
RelayRate uint32 // Base relay price mSAT/Mb.
Services services.Services // Services offered by this peer.
Load byte
payments.PayChan
Transport tpt.Transport
}
// NewNode creates a new Node. The transport should be from either dialing out or
// a peer dialing in and the self model does not need to do this.
func NewNode(addr *netip.AddrPort, keys *crypto.Keys, tpt tpt.Transport,
relayRate uint32) (n *Node, id nonce.ID) {
id = nonce.NewID()
n = &Node{
ID: id,
AddrPort: addr,
Identity: keys,
RelayRate: relayRate,
PayChan: make(payments.PayChan, PaymentChanBuffers),
Transport: tpt,
}
return
}
// AddService adds a service to a Node.
func (n *Node) AddService(s *services.Service) (e error) {
n.Lock()
defer n.Unlock()
for i := range n.Services {
if n.Services[i].Port == s.Port {
return fmt.Errorf("service already exists for port %d", s.Port)
}
}
n.Services = append(n.Services, s)
return
}
// DeleteService removes a service from a Node.
func (n *Node) DeleteService(port uint16) {
n.Lock()
defer n.Unlock()
for i := range n.Services {
if n.Services[i].Port == port {
if i < 1 {
n.Services = n.Services[1:]
} else {
n.Services = append(n.Services[:i],
n.Services[i+1:]...)
}
return
}
}
}
// FindService searches for a local service with a given port number.
func (n *Node) FindService(port uint16) (svc *services.Service) {
n.Lock()
defer n.Unlock()
for i := range n.Services {
if n.Services[i].Port == port {
return n.Services[i]
}
}
return
}
// ReceiveFrom returns the channel that receives messages for a given port.
func (n *Node) ReceiveFrom(port uint16) (b <-chan slice.Bytes) {
n.Lock()
defer n.Unlock()
for i := range n.Services {
if n.Services[i].Port == port {
log.T.Ln("receive from")
b = n.Services[i].Receive()
return
}
}
return
}
// SendTo delivers a message to a service identified by its port.
func (n *Node) SendTo(port uint16, b slice.Bytes) (e error) {
n.Lock()
defer n.Unlock()
e = fmt.Errorf("%s port not registered %d", n.AddrPort.String(), port)
for i := range n.Services {
if n.Services[i].Port == port {
e = n.Services[i].Send(b)
return
}
}
return
}