mirror of https://github.com/status-im/nim-eth.git
Enable chronos dualstack with new constructor. (#681)
* Add constructor which will use latest chronos feature. * Add ability to send to IPv4 addresses via dualstack socket. * Fix decoding IPv4 mapped addresses. * Use `*` instead of IPv6 address `::`. * Removing debugging log statements. * Address review comments. * Remove debugging statements. * Eliminate unnecessary variables.
This commit is contained in:
parent
d66a29db7c
commit
4cd9e27c09
|
@ -123,6 +123,10 @@ const
|
|||
## call
|
||||
|
||||
type
|
||||
OptAddress* = object
|
||||
ip*: Opt[IpAddress]
|
||||
port*: Port
|
||||
|
||||
DiscoveryConfig* = object
|
||||
tableIpLimits*: TableIpLimits
|
||||
bitsPerHop*: int
|
||||
|
@ -133,7 +137,7 @@ type
|
|||
transp: DatagramTransport
|
||||
localNode*: Node
|
||||
privateKey: PrivateKey
|
||||
bindAddress: Address ## UDP binding address
|
||||
bindAddress: OptAddress ## UDP binding address
|
||||
pendingRequests: Table[AESGCMNonce, PendingRequest]
|
||||
routingTable*: RoutingTable
|
||||
codec*: Codec
|
||||
|
@ -270,7 +274,7 @@ proc sendTo(d: Protocol, a: Address, data: seq[byte]): Future[void] {.async.} =
|
|||
# One case that needs this error available upwards is when revalidating
|
||||
# nodes. Else the revalidation might end up clearing the routing tabl
|
||||
# because of ping failures due to own network connection failure.
|
||||
warn "Discovery send failed", msg = e.msg, address = a
|
||||
warn "Discovery send failed", msg = e.msg, address = $ta
|
||||
|
||||
proc send*(d: Protocol, a: Address, data: seq[byte]) =
|
||||
asyncSpawn sendTo(d, a, data)
|
||||
|
@ -478,13 +482,7 @@ proc processClient(transp: DatagramTransport, raddr: TransportAddress):
|
|||
warn "Transport getMessage", exception = e.name, msg = e.msg
|
||||
return
|
||||
|
||||
let ip = try: raddr.address()
|
||||
except ValueError as e:
|
||||
error "Not a valid IpAddress", exception = e.name, msg = e.msg
|
||||
return
|
||||
let a = Address(ip: ip, port: raddr.port)
|
||||
|
||||
proto.receive(a, buf)
|
||||
proto.receive(Address(ip: raddr.toIpAddress(), port: raddr.port), buf)
|
||||
|
||||
proc replaceNode(d: Protocol, n: Node) =
|
||||
if n.record notin d.bootstrapRecords:
|
||||
|
@ -1006,7 +1004,7 @@ proc newProtocol*(
|
|||
Protocol(
|
||||
privateKey: privKey,
|
||||
localNode: node,
|
||||
bindAddress: Address(ip: bindIp, port: bindPort),
|
||||
bindAddress: OptAddress(ip: Opt.some(bindIp), port: bindPort),
|
||||
codec: Codec(localNode: node, privKey: privKey,
|
||||
sessions: Sessions.init(256)),
|
||||
bootstrapRecords: @bootstrapRecords,
|
||||
|
@ -1018,17 +1016,86 @@ proc newProtocol*(
|
|||
responseTimeout: config.responseTimeout,
|
||||
rng: rng)
|
||||
|
||||
template listeningAddress*(p: Protocol): Address =
|
||||
p.bindAddress
|
||||
proc newProtocol*(
|
||||
privKey: PrivateKey,
|
||||
enrIp: Option[IpAddress],
|
||||
enrTcpPort, enrUdpPort: Option[Port],
|
||||
localEnrFields: openArray[(string, seq[byte])] = [],
|
||||
bootstrapRecords: openArray[Record] = [],
|
||||
previousRecord = none[enr.Record](),
|
||||
bindPort: Port,
|
||||
bindIp: Opt[IpAddress],
|
||||
enrAutoUpdate = false,
|
||||
config = defaultDiscoveryConfig,
|
||||
rng = newRng()): Protocol =
|
||||
let
|
||||
customEnrFields = mapIt(localEnrFields, toFieldPair(it[0], it[1]))
|
||||
record =
|
||||
if previousRecord.isSome():
|
||||
var res = previousRecord.get()
|
||||
res.update(privKey, enrIp, enrTcpPort, enrUdpPort,
|
||||
customEnrFields).expect("Record within size limits and correct key")
|
||||
res
|
||||
else:
|
||||
enr.Record.init(1, privKey, enrIp, enrTcpPort, enrUdpPort,
|
||||
customEnrFields).expect("Record within size limits")
|
||||
|
||||
proc open*(d: Protocol) {.raises: [CatchableError].} =
|
||||
info "Discovery ENR initialized", enrAutoUpdate, seqNum = record.seqNum,
|
||||
ip = enrIp, tcpPort = enrTcpPort, udpPort = enrUdpPort,
|
||||
customEnrFields, uri = toURI(record)
|
||||
|
||||
if enrIp.isNone():
|
||||
if enrAutoUpdate:
|
||||
notice "No external IP provided for the ENR, this node will not be " &
|
||||
"discoverable until the ENR is updated with the discovered " &
|
||||
"external IP address"
|
||||
else:
|
||||
warn "No external IP provided for the ENR, this node will not be " &
|
||||
"discoverable"
|
||||
|
||||
let node = newNode(record).expect("Properly initialized record")
|
||||
|
||||
doAssert not(isNil(rng)), "RNG initialization failed"
|
||||
|
||||
Protocol(
|
||||
privateKey: privKey,
|
||||
localNode: node,
|
||||
bindAddress: OptAddress(ip: bindIp, port: bindPort),
|
||||
codec: Codec(localNode: node, privKey: privKey,
|
||||
sessions: Sessions.init(256)),
|
||||
bootstrapRecords: @bootstrapRecords,
|
||||
ipVote: IpVote.init(),
|
||||
enrAutoUpdate: enrAutoUpdate,
|
||||
routingTable: RoutingTable.init(
|
||||
node, config.bitsPerHop, config.tableIpLimits, rng),
|
||||
handshakeTimeout: config.handshakeTimeout,
|
||||
responseTimeout: config.responseTimeout,
|
||||
rng: rng)
|
||||
|
||||
proc `$`*(a: OptAddress): string =
|
||||
if a.ip.isNone():
|
||||
"*:" & $a.port
|
||||
else:
|
||||
$a.ip.get() & ":" & $a.port
|
||||
|
||||
chronicles.formatIt(OptAddress): $it
|
||||
|
||||
template listeningAddress*(p: Protocol): Address =
|
||||
if p.bindAddress.ip.isNone():
|
||||
let ta = getAutoAddress(p.bindAddress.port)
|
||||
Address(ta.toIpAddress(), ta.port)
|
||||
else:
|
||||
Address(p.bindAddress.ip.get(), p.bindAddress.port)
|
||||
|
||||
proc open*(d: Protocol) {.raises: [TransportOsError].} =
|
||||
info "Starting discovery node", node = d.localNode,
|
||||
bindAddress = d.bindAddress
|
||||
|
||||
# TODO allow binding to specific IP / IPv6 / etc
|
||||
let ta = initTAddress(d.bindAddress.ip, d.bindAddress.port)
|
||||
d.transp = newDatagramTransport(processClient, udata = d, local = ta)
|
||||
|
||||
d.transp =
|
||||
newDatagramTransport(processClient, udata = d,
|
||||
localPort = d.bindAddress.port,
|
||||
local = d.bindAddress.ip)
|
||||
d.seedTable()
|
||||
|
||||
proc start*(d: Protocol) =
|
||||
|
|
Loading…
Reference in New Issue