lnd/chanacceptor/chainedacceptor.go
nsa 2bd2e2e5ce
chanacceptor: Adding Chained and RPC acceptors
This commit introduces the chanacceptor package which is used
to determine, by a set of heuristics, which open channel messages
to accept and reject. Currently, two acceptors are implemented
via the ChannelAcceptor interface: ChainedAcceptor and RPCAcceptor.
The RPCAcceptor allows the RPC client to respond to the open channel
request, and the ChainedAcceptor allows a conjunction of acceptors
to be used.
2019-09-25 12:07:30 -04:00

66 lines
1.8 KiB
Go

package chanacceptor
import (
"sync"
"sync/atomic"
)
// ChainedAcceptor represents a conjunction of ChannelAcceptor results.
type ChainedAcceptor struct {
// acceptors is a map of ChannelAcceptors that will be evaluated when
// the ChainedAcceptor's Accept method is called.
acceptors map[uint64]ChannelAcceptor
acceptorsMtx sync.RWMutex
acceptorID uint64 // To be used atomically.
}
// NewChainedAcceptor initializes a ChainedAcceptor.
func NewChainedAcceptor() *ChainedAcceptor {
return &ChainedAcceptor{
acceptors: make(map[uint64]ChannelAcceptor),
}
}
// AddAcceptor adds a ChannelAcceptor to this ChainedAcceptor.
func (c *ChainedAcceptor) AddAcceptor(acceptor ChannelAcceptor) uint64 {
id := atomic.AddUint64(&c.acceptorID, 1)
c.acceptorsMtx.Lock()
c.acceptors[id] = acceptor
c.acceptorsMtx.Unlock()
// Return the id so that a caller can call RemoveAcceptor.
return id
}
// RemoveAcceptor removes a ChannelAcceptor from this ChainedAcceptor given
// an ID.
func (c *ChainedAcceptor) RemoveAcceptor(id uint64) {
c.acceptorsMtx.Lock()
delete(c.acceptors, id)
c.acceptorsMtx.Unlock()
}
// Accept evaluates the results of all ChannelAcceptors in the acceptors map
// and returns the conjunction of all these predicates.
//
// NOTE: Part of the ChannelAcceptor interface.
func (c *ChainedAcceptor) Accept(req *ChannelAcceptRequest) bool {
result := true
c.acceptorsMtx.RLock()
for _, acceptor := range c.acceptors {
// We call Accept first in case any acceptor (perhaps an RPCAcceptor)
// wishes to be notified about ChannelAcceptRequest.
result = acceptor.Accept(req) && result
}
c.acceptorsMtx.RUnlock()
return result
}
// A compile-time constraint to ensure ChainedAcceptor implements the
// ChannelAcceptor interface.
var _ ChannelAcceptor = (*ChainedAcceptor)(nil)