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
|
## call
|
||||||
|
|
||||||
type
|
type
|
||||||
|
OptAddress* = object
|
||||||
|
ip*: Opt[IpAddress]
|
||||||
|
port*: Port
|
||||||
|
|
||||||
DiscoveryConfig* = object
|
DiscoveryConfig* = object
|
||||||
tableIpLimits*: TableIpLimits
|
tableIpLimits*: TableIpLimits
|
||||||
bitsPerHop*: int
|
bitsPerHop*: int
|
||||||
|
@ -133,7 +137,7 @@ type
|
||||||
transp: DatagramTransport
|
transp: DatagramTransport
|
||||||
localNode*: Node
|
localNode*: Node
|
||||||
privateKey: PrivateKey
|
privateKey: PrivateKey
|
||||||
bindAddress: Address ## UDP binding address
|
bindAddress: OptAddress ## UDP binding address
|
||||||
pendingRequests: Table[AESGCMNonce, PendingRequest]
|
pendingRequests: Table[AESGCMNonce, PendingRequest]
|
||||||
routingTable*: RoutingTable
|
routingTable*: RoutingTable
|
||||||
codec*: Codec
|
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
|
# One case that needs this error available upwards is when revalidating
|
||||||
# nodes. Else the revalidation might end up clearing the routing tabl
|
# nodes. Else the revalidation might end up clearing the routing tabl
|
||||||
# because of ping failures due to own network connection failure.
|
# 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]) =
|
proc send*(d: Protocol, a: Address, data: seq[byte]) =
|
||||||
asyncSpawn sendTo(d, a, data)
|
asyncSpawn sendTo(d, a, data)
|
||||||
|
@ -478,13 +482,7 @@ proc processClient(transp: DatagramTransport, raddr: TransportAddress):
|
||||||
warn "Transport getMessage", exception = e.name, msg = e.msg
|
warn "Transport getMessage", exception = e.name, msg = e.msg
|
||||||
return
|
return
|
||||||
|
|
||||||
let ip = try: raddr.address()
|
proto.receive(Address(ip: raddr.toIpAddress(), port: raddr.port), buf)
|
||||||
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)
|
|
||||||
|
|
||||||
proc replaceNode(d: Protocol, n: Node) =
|
proc replaceNode(d: Protocol, n: Node) =
|
||||||
if n.record notin d.bootstrapRecords:
|
if n.record notin d.bootstrapRecords:
|
||||||
|
@ -1006,7 +1004,7 @@ proc newProtocol*(
|
||||||
Protocol(
|
Protocol(
|
||||||
privateKey: privKey,
|
privateKey: privKey,
|
||||||
localNode: node,
|
localNode: node,
|
||||||
bindAddress: Address(ip: bindIp, port: bindPort),
|
bindAddress: OptAddress(ip: Opt.some(bindIp), port: bindPort),
|
||||||
codec: Codec(localNode: node, privKey: privKey,
|
codec: Codec(localNode: node, privKey: privKey,
|
||||||
sessions: Sessions.init(256)),
|
sessions: Sessions.init(256)),
|
||||||
bootstrapRecords: @bootstrapRecords,
|
bootstrapRecords: @bootstrapRecords,
|
||||||
|
@ -1018,17 +1016,86 @@ proc newProtocol*(
|
||||||
responseTimeout: config.responseTimeout,
|
responseTimeout: config.responseTimeout,
|
||||||
rng: rng)
|
rng: rng)
|
||||||
|
|
||||||
template listeningAddress*(p: Protocol): Address =
|
proc newProtocol*(
|
||||||
p.bindAddress
|
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,
|
info "Starting discovery node", node = d.localNode,
|
||||||
bindAddress = d.bindAddress
|
bindAddress = d.bindAddress
|
||||||
|
|
||||||
# TODO allow binding to specific IP / IPv6 / etc
|
# TODO allow binding to specific IP / IPv6 / etc
|
||||||
let ta = initTAddress(d.bindAddress.ip, d.bindAddress.port)
|
d.transp =
|
||||||
d.transp = newDatagramTransport(processClient, udata = d, local = ta)
|
newDatagramTransport(processClient, udata = d,
|
||||||
|
localPort = d.bindAddress.port,
|
||||||
|
local = d.bindAddress.ip)
|
||||||
d.seedTable()
|
d.seedTable()
|
||||||
|
|
||||||
proc start*(d: Protocol) =
|
proc start*(d: Protocol) =
|
||||||
|
|
Loading…
Reference in New Issue