use a builder pattern to build the switch (#551)
* use a builder pattern to build the switch * with with * more refs
This commit is contained in:
parent
df497660bc
commit
795a651839
|
@ -26,7 +26,7 @@ import
|
|||
peerid,
|
||||
peerinfo,
|
||||
multiaddress,
|
||||
standard_setup,
|
||||
builders,
|
||||
crypto/crypto]
|
||||
|
||||
import bearssl
|
||||
|
@ -36,4 +36,4 @@ export
|
|||
connection, multiaddress, crypto, lpstream,
|
||||
bufferstream, bearssl, muxer, mplex, transport,
|
||||
tcptransport, noise, errors, cid, multihash,
|
||||
multicodec, standard_setup
|
||||
multicodec, builders
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
import
|
||||
options, tables, chronos, bearssl,
|
||||
switch, peerid, peerinfo, stream/connection, multiaddress,
|
||||
crypto/crypto, transports/[transport, tcptransport],
|
||||
muxers/[muxer, mplex/mplex],
|
||||
protocols/[identify, secure/secure, secure/noise],
|
||||
connmanager
|
||||
|
||||
export
|
||||
switch, peerid, peerinfo, connection, multiaddress, crypto
|
||||
|
||||
type
|
||||
SecureProtocol* {.pure.} = enum
|
||||
Noise,
|
||||
Secio {.deprecated.}
|
||||
|
||||
SwitchBuilder* = ref object
|
||||
privKey: Option[PrivateKey]
|
||||
address: MultiAddress
|
||||
secureManagers: seq[SecureProtocol]
|
||||
tcpTransportFlags: Option[set[ServerFlags]]
|
||||
rng: ref BrHmacDrbgContext
|
||||
inTimeout: Duration
|
||||
outTimeout: Duration
|
||||
maxConnections: int
|
||||
maxIn: int
|
||||
maxOut: int
|
||||
maxConnsPerPeer: int
|
||||
protoVersion: Option[string]
|
||||
agentVersion: Option[string]
|
||||
|
||||
proc init*(_: type[SwitchBuilder]): SwitchBuilder =
|
||||
SwitchBuilder(
|
||||
privKey: none(PrivateKey),
|
||||
address: MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet(),
|
||||
secureManagers: @[],
|
||||
tcpTransportFlags: block:
|
||||
let flags: set[ServerFlags] = {}
|
||||
some(flags),
|
||||
rng: newRng(),
|
||||
inTimeout: 5.minutes,
|
||||
outTimeout: 5.minutes,
|
||||
maxConnections: MaxConnections,
|
||||
maxIn: -1,
|
||||
maxOut: -1,
|
||||
maxConnsPerPeer: MaxConnectionsPerPeer,
|
||||
protoVersion: none(string),
|
||||
agentVersion: none(string))
|
||||
|
||||
# so I tried using var inpit and return but did not work...
|
||||
# as in proc privateKey*(builder: var SwitchBuilder, privateKey: PrivateKey): var SwitchBuilder =
|
||||
# so in nim we are stuck with this hardly efficient way and hopey compiler figures it out.. heh
|
||||
# maybe {.byref.} works.... I would not bet on it but let's use it.
|
||||
|
||||
proc withPrivateKey*(b: SwitchBuilder, privateKey: PrivateKey): SwitchBuilder =
|
||||
b.privKey = some(privateKey)
|
||||
b
|
||||
|
||||
proc withAddress*(b: SwitchBuilder, address: MultiAddress): SwitchBuilder =
|
||||
b.address = address
|
||||
b
|
||||
|
||||
proc withSecureManager*(b: SwitchBuilder, secureManager: SecureProtocol): SwitchBuilder =
|
||||
b.secureManagers &= secureManager
|
||||
b
|
||||
|
||||
proc withTcpTransport*(b: SwitchBuilder, flags: set[ServerFlags] = {}): SwitchBuilder =
|
||||
b.tcpTransportFlags = some(flags)
|
||||
b
|
||||
|
||||
proc withRng*(b: SwitchBuilder, rng: ref BrHmacDrbgContext): SwitchBuilder =
|
||||
b.rng = rng
|
||||
b
|
||||
|
||||
proc withInTimeout*(b: SwitchBuilder, inTimeout: Duration): SwitchBuilder =
|
||||
b.inTimeout = inTimeout
|
||||
b
|
||||
|
||||
proc withOutTimeout*(b: SwitchBuilder, outTimeout: Duration): SwitchBuilder =
|
||||
b.outTimeout = outTimeout
|
||||
b
|
||||
|
||||
proc withMaxConnections*(b: SwitchBuilder, maxConnections: int): SwitchBuilder =
|
||||
b.maxConnections = maxConnections
|
||||
b
|
||||
|
||||
proc withMaxIn*(b: SwitchBuilder, maxIn: int): SwitchBuilder =
|
||||
b.maxIn = maxIn
|
||||
b
|
||||
|
||||
proc withMaxOut*(b: SwitchBuilder, maxOut: int): SwitchBuilder =
|
||||
b.maxOut = maxOut
|
||||
b
|
||||
|
||||
proc withMaxConnsPerPeer*(b: SwitchBuilder, maxConnsPerPeer: int): SwitchBuilder =
|
||||
b.maxConnsPerPeer = maxConnsPerPeer
|
||||
b
|
||||
|
||||
proc withProtoVersion*(b: SwitchBuilder, protoVersion: string): SwitchBuilder =
|
||||
b.protoVersion = some(protoVersion)
|
||||
b
|
||||
|
||||
proc withAgentVersion*(b: SwitchBuilder, agentVersion: string): SwitchBuilder =
|
||||
b.agentVersion = some(agentVersion)
|
||||
b
|
||||
|
||||
proc build*(b: SwitchBuilder): Switch =
|
||||
let
|
||||
inTimeout = b.inTimeout
|
||||
outTimeout = b.outTimeout
|
||||
|
||||
proc createMplex(conn: Connection): Muxer =
|
||||
Mplex.init(
|
||||
conn,
|
||||
inTimeout = inTimeout,
|
||||
outTimeout = outTimeout)
|
||||
|
||||
if b.rng == nil: # newRng could fail
|
||||
raise (ref CatchableError)(msg: "Cannot initialize RNG")
|
||||
|
||||
let
|
||||
seckey = b.privKey.get(otherwise = PrivateKey.random(b.rng[]).tryGet())
|
||||
peerInfo = block:
|
||||
let info = PeerInfo.init(seckey, [b.address])
|
||||
if b.protoVersion.isSome():
|
||||
info.protoVersion = b.protoVersion.get()
|
||||
if b.agentVersion.isSome():
|
||||
info.agentVersion = b.agentVersion.get()
|
||||
info
|
||||
mplexProvider = newMuxerProvider(createMplex, MplexCodec)
|
||||
transports = block:
|
||||
var transports: seq[Transport]
|
||||
if b.tcpTransportFlags.isSome():
|
||||
transports &= Transport(TcpTransport.init(b.tcpTransportFlags.get()))
|
||||
transports
|
||||
muxers = {MplexCodec: mplexProvider}.toTable
|
||||
identify = newIdentify(peerInfo)
|
||||
|
||||
if b.secureManagers.len == 0:
|
||||
b.secureManagers &= SecureProtocol.Noise
|
||||
|
||||
var
|
||||
secureManagerInstances: seq[Secure]
|
||||
for sec in b.secureManagers:
|
||||
case sec
|
||||
of SecureProtocol.Noise:
|
||||
secureManagerInstances &= newNoise(b.rng, seckey).Secure
|
||||
of SecureProtocol.Secio:
|
||||
quit("Secio is deprecated!") # use of secio is unsafe
|
||||
|
||||
let switch = newSwitch(
|
||||
peerInfo,
|
||||
transports,
|
||||
identify,
|
||||
muxers,
|
||||
secureManagers = secureManagerInstances,
|
||||
maxConnections = b.maxConnections,
|
||||
maxIn = b.maxIn,
|
||||
maxOut = b.maxOut,
|
||||
maxConnsPerPeer = b.maxConnsPerPeer)
|
||||
|
||||
return switch
|
||||
|
||||
proc newStandardSwitch*(privKey = none(PrivateKey),
|
||||
address = MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet(),
|
||||
secureManagers: openarray[SecureProtocol] = [
|
||||
SecureProtocol.Noise,
|
||||
],
|
||||
transportFlags: set[ServerFlags] = {},
|
||||
rng = newRng(),
|
||||
inTimeout: Duration = 5.minutes,
|
||||
outTimeout: Duration = 5.minutes,
|
||||
maxConnections = MaxConnections,
|
||||
maxIn = -1,
|
||||
maxOut = -1,
|
||||
maxConnsPerPeer = MaxConnectionsPerPeer): Switch =
|
||||
var b = SwitchBuilder
|
||||
.init()
|
||||
.withAddress(address)
|
||||
.withRng(rng)
|
||||
.withInTimeout(inTimeout)
|
||||
.withOutTimeout(outTimeout)
|
||||
.withMaxConnections(maxConnections)
|
||||
.withMaxIn(maxIn)
|
||||
.withMaxOut(maxOut)
|
||||
.withMaxConnsPerPeer(maxConnsPerPeer)
|
||||
.withTcpTransport(transportFlags)
|
||||
|
||||
if privKey.isSome():
|
||||
b = b.withPrivateKey(privKey.get())
|
||||
|
||||
for sm in secureManagers:
|
||||
b = b.withSecureManager(sm)
|
||||
|
||||
b.build()
|
|
@ -1,67 +0,0 @@
|
|||
import
|
||||
options, tables, chronos, bearssl,
|
||||
switch, peerid, peerinfo, stream/connection, multiaddress,
|
||||
crypto/crypto, transports/[transport, tcptransport],
|
||||
muxers/[muxer, mplex/mplex],
|
||||
protocols/[identify, secure/secure, secure/noise],
|
||||
connmanager
|
||||
|
||||
export
|
||||
switch, peerid, peerinfo, connection, multiaddress, crypto
|
||||
|
||||
type
|
||||
SecureProtocol* {.pure.} = enum
|
||||
Noise,
|
||||
Secio {.deprecated.}
|
||||
|
||||
proc newStandardSwitch*(privKey = none(PrivateKey),
|
||||
address = MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet(),
|
||||
secureManagers: openarray[SecureProtocol] = [
|
||||
SecureProtocol.Noise,
|
||||
],
|
||||
transportFlags: set[ServerFlags] = {},
|
||||
rng = newRng(),
|
||||
inTimeout: Duration = 5.minutes,
|
||||
outTimeout: Duration = 5.minutes,
|
||||
maxConnections = MaxConnections,
|
||||
maxIn = -1,
|
||||
maxOut = -1,
|
||||
maxConnsPerPeer = MaxConnectionsPerPeer): Switch =
|
||||
proc createMplex(conn: Connection): Muxer =
|
||||
Mplex.init(
|
||||
conn,
|
||||
inTimeout = inTimeout,
|
||||
outTimeout = outTimeout)
|
||||
|
||||
if rng == nil: # newRng could fail
|
||||
raise (ref CatchableError)(msg: "Cannot initialize RNG")
|
||||
|
||||
let
|
||||
seckey = privKey.get(otherwise = PrivateKey.random(rng[]).tryGet())
|
||||
peerInfo = PeerInfo.init(seckey, [address])
|
||||
mplexProvider = newMuxerProvider(createMplex, MplexCodec)
|
||||
transports = @[Transport(TcpTransport.init(transportFlags))]
|
||||
muxers = {MplexCodec: mplexProvider}.toTable
|
||||
identify = newIdentify(peerInfo)
|
||||
|
||||
var
|
||||
secureManagerInstances: seq[Secure]
|
||||
for sec in secureManagers:
|
||||
case sec
|
||||
of SecureProtocol.Noise:
|
||||
secureManagerInstances &= newNoise(rng, seckey).Secure
|
||||
of SecureProtocol.Secio:
|
||||
quit("Secio is deprecated!") # use of secio is unsafe
|
||||
|
||||
let switch = newSwitch(
|
||||
peerInfo,
|
||||
transports,
|
||||
identify,
|
||||
muxers,
|
||||
secureManagers = secureManagerInstances,
|
||||
maxConnections = maxConnections,
|
||||
maxIn = maxIn,
|
||||
maxOut = maxOut,
|
||||
maxConnsPerPeer = maxConnsPerPeer)
|
||||
|
||||
return switch
|
|
@ -5,7 +5,7 @@ include ../../libp2p/protocols/pubsub/gossipsub
|
|||
import options
|
||||
import unittest, bearssl
|
||||
import stew/byteutils
|
||||
import ../../libp2p/standard_setup
|
||||
import ../../libp2p/builders
|
||||
import ../../libp2p/errors
|
||||
import ../../libp2p/crypto/crypto
|
||||
import ../../libp2p/stream/bufferstream
|
||||
|
|
|
@ -6,13 +6,13 @@ const
|
|||
|
||||
import random, tables
|
||||
import chronos
|
||||
import ../../libp2p/[standard_setup,
|
||||
import ../../libp2p/[builders,
|
||||
protocols/pubsub/pubsub,
|
||||
protocols/pubsub/gossipsub,
|
||||
protocols/pubsub/floodsub,
|
||||
protocols/secure/secure]
|
||||
|
||||
export standard_setup
|
||||
export builders
|
||||
|
||||
randomize()
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import ../libp2p/[daemon/daemonapi,
|
|||
cid,
|
||||
varint,
|
||||
multihash,
|
||||
standard_setup,
|
||||
builders,
|
||||
peerid,
|
||||
peerinfo,
|
||||
switch,
|
||||
|
|
|
@ -7,7 +7,7 @@ import nimcrypto/sysrand
|
|||
import ../libp2p/[errors,
|
||||
switch,
|
||||
multistream,
|
||||
standard_setup,
|
||||
builders,
|
||||
stream/bufferstream,
|
||||
stream/connection,
|
||||
multiaddress,
|
||||
|
|
Loading…
Reference in New Issue