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.
This commit is contained in:
parent
7c6cee7c4f
commit
2bd2e2e5ce
65
chanacceptor/chainedacceptor.go
Normal file
65
chanacceptor/chainedacceptor.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
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)
|
25
chanacceptor/interface.go
Normal file
25
chanacceptor/interface.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package chanacceptor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/btcsuite/btcd/btcec"
|
||||||
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ChannelAcceptRequest is a struct containing the requesting node's public key
|
||||||
|
// along with the lnwire.OpenChannel message that they sent when requesting an
|
||||||
|
// inbound channel. This information is provided to each acceptor so that they
|
||||||
|
// can each leverage their own decision-making with this information.
|
||||||
|
type ChannelAcceptRequest struct {
|
||||||
|
// Node is the public key of the node requesting to open a channel.
|
||||||
|
Node *btcec.PublicKey
|
||||||
|
|
||||||
|
// OpenChanMsg is the actual OpenChannel protocol message that the peer
|
||||||
|
// sent to us.
|
||||||
|
OpenChanMsg *lnwire.OpenChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChannelAcceptor is an interface that represents a predicate on the data
|
||||||
|
// contained in ChannelAcceptRequest.
|
||||||
|
type ChannelAcceptor interface {
|
||||||
|
Accept(req *ChannelAcceptRequest) bool
|
||||||
|
}
|
27
chanacceptor/rpcacceptor.go
Normal file
27
chanacceptor/rpcacceptor.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package chanacceptor
|
||||||
|
|
||||||
|
// RPCAcceptor represents the RPC-controlled variant of the ChannelAcceptor.
|
||||||
|
// One RPCAcceptor allows one RPC client.
|
||||||
|
type RPCAcceptor struct {
|
||||||
|
acceptClosure func(req *ChannelAcceptRequest) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept is a predicate on the ChannelAcceptRequest which is sent to the RPC
|
||||||
|
// client who will respond with the ultimate decision. This assumes an accept
|
||||||
|
// closure has been specified during creation.
|
||||||
|
//
|
||||||
|
// NOTE: Part of the ChannelAcceptor interface.
|
||||||
|
func (r *RPCAcceptor) Accept(req *ChannelAcceptRequest) bool {
|
||||||
|
return r.acceptClosure(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRPCAcceptor creates and returns an instance of the RPCAcceptor.
|
||||||
|
func NewRPCAcceptor(closure func(*ChannelAcceptRequest) bool) *RPCAcceptor {
|
||||||
|
return &RPCAcceptor{
|
||||||
|
acceptClosure: closure,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A compile-time constraint to ensure RPCAcceptor implements the ChannelAcceptor
|
||||||
|
// interface.
|
||||||
|
var _ ChannelAcceptor = (*RPCAcceptor)(nil)
|
Loading…
Reference in New Issue
Block a user