mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-14 06:15:57 +00:00
Some more Options to Opt and similar changes (#1611)
Includes nim-eth bump.
This commit is contained in:
parent
7dbcf94280
commit
8ebac4c878
@ -344,21 +344,21 @@ proc get(db: ContentDB, T: type BlockHeader, contentId: ContentId): Opt[T] =
|
|||||||
|
|
||||||
proc get(db: ContentDB, T: type BlockBody, contentId: ContentId,
|
proc get(db: ContentDB, T: type BlockBody, contentId: ContentId,
|
||||||
header: BlockHeader): Opt[T] =
|
header: BlockHeader): Opt[T] =
|
||||||
let encoded = db.get(contentId)
|
let encoded = db.get(contentId).valueOr:
|
||||||
if encoded.isNone():
|
|
||||||
return Opt.none(T)
|
return Opt.none(T)
|
||||||
|
|
||||||
let timestamp = Moment.init(header.timestamp.toUnix(), Second)
|
let
|
||||||
let body =
|
timestamp = Moment.init(header.timestamp.toUnix(), Second)
|
||||||
if isShanghai(chainConfig, timestamp):
|
body =
|
||||||
BlockBody.fromPortalBlockBodyOrRaise(
|
if isShanghai(chainConfig, timestamp):
|
||||||
decodeSszOrRaise(encoded.get(), PortalBlockBodyShanghai))
|
BlockBody.fromPortalBlockBodyOrRaise(
|
||||||
elif isPoSBlock(chainConfig, header.blockNumber.truncate(uint64)):
|
decodeSszOrRaise(encoded, PortalBlockBodyShanghai))
|
||||||
BlockBody.fromPortalBlockBodyOrRaise(
|
elif isPoSBlock(chainConfig, header.blockNumber.truncate(uint64)):
|
||||||
decodeSszOrRaise(encoded.get(), PortalBlockBodyLegacy))
|
BlockBody.fromPortalBlockBodyOrRaise(
|
||||||
else:
|
decodeSszOrRaise(encoded, PortalBlockBodyLegacy))
|
||||||
BlockBody.fromPortalBlockBodyOrRaise(
|
else:
|
||||||
decodeSszOrRaise(encoded.get(), PortalBlockBodyLegacy))
|
BlockBody.fromPortalBlockBodyOrRaise(
|
||||||
|
decodeSszOrRaise(encoded, PortalBlockBodyLegacy))
|
||||||
|
|
||||||
Opt.some(body)
|
Opt.some(body)
|
||||||
|
|
||||||
@ -733,17 +733,13 @@ proc validateContent(
|
|||||||
for i, contentItem in contentItems:
|
for i, contentItem in contentItems:
|
||||||
let contentKey = contentKeys[i]
|
let contentKey = contentKeys[i]
|
||||||
if await n.validateContent(contentItem, contentKey):
|
if await n.validateContent(contentItem, contentKey):
|
||||||
let contentIdOpt = n.portalProtocol.toContentId(contentKey)
|
let contentId = n.portalProtocol.toContentId(contentKey).valueOr:
|
||||||
if contentIdOpt.isNone():
|
|
||||||
error "Received offered content with invalid content key", contentKey
|
error "Received offered content with invalid content key", contentKey
|
||||||
return false
|
return false
|
||||||
|
|
||||||
let contentId = contentIdOpt.get()
|
|
||||||
|
|
||||||
n.portalProtocol.storeContent(contentKey, contentId, contentItem)
|
n.portalProtocol.storeContent(contentKey, contentId, contentItem)
|
||||||
|
|
||||||
info "Received offered content validated successfully", contentKey
|
info "Received offered content validated successfully", contentKey
|
||||||
|
|
||||||
else:
|
else:
|
||||||
error "Received offered content failed validation", contentKey
|
error "Received offered content failed validation", contentKey
|
||||||
return false
|
return false
|
||||||
|
@ -223,7 +223,7 @@ proc addNode*(p: PortalProtocol, r: Record): bool =
|
|||||||
else:
|
else:
|
||||||
false
|
false
|
||||||
|
|
||||||
proc getNode*(p: PortalProtocol, id: NodeId): Option[Node] =
|
proc getNode*(p: PortalProtocol, id: NodeId): Opt[Node] =
|
||||||
p.routingTable.getNode(id)
|
p.routingTable.getNode(id)
|
||||||
|
|
||||||
func localNode*(p: PortalProtocol): Node = p.baseProtocol.localNode
|
func localNode*(p: PortalProtocol): Node = p.baseProtocol.localNode
|
||||||
@ -316,15 +316,13 @@ proc handleFindContent(
|
|||||||
maxPayloadSize = maxDiscv5PacketSize - talkRespOverhead - contentOverhead
|
maxPayloadSize = maxDiscv5PacketSize - talkRespOverhead - contentOverhead
|
||||||
enrOverhead = 4 # per added ENR, 4 bytes offset overhead
|
enrOverhead = 4 # per added ENR, 4 bytes offset overhead
|
||||||
|
|
||||||
let contentIdResult = p.toContentId(fc.contentKey)
|
let contentId = p.toContentId(fc.contentKey).valueOr:
|
||||||
|
|
||||||
if contentIdResult.isErr:
|
|
||||||
# Return empty response when content key validation fails
|
# Return empty response when content key validation fails
|
||||||
# TODO: Better would be to return no message at all? Needs changes on
|
# TODO: Better would be to return no message at all? Needs changes on
|
||||||
# discv5 layer.
|
# discv5 layer.
|
||||||
return @[]
|
return @[]
|
||||||
|
|
||||||
let contentResult = p.dbGet(fc.contentKey, contentIdResult.get())
|
let contentResult = p.dbGet(fc.contentKey, contentId)
|
||||||
|
|
||||||
if contentResult.isOk():
|
if contentResult.isOk():
|
||||||
let content = contentResult.get()
|
let content = contentResult.get()
|
||||||
@ -340,7 +338,7 @@ proc handleFindContent(
|
|||||||
# Don't have the content, send closest neighbours to content id.
|
# Don't have the content, send closest neighbours to content id.
|
||||||
let
|
let
|
||||||
closestNodes = p.routingTable.neighbours(
|
closestNodes = p.routingTable.neighbours(
|
||||||
NodeId(contentIdResult.get()), seenOnly = true)
|
NodeId(contentId), seenOnly = true)
|
||||||
enrs = truncateEnrs(closestNodes, maxPayloadSize, enrOverhead)
|
enrs = truncateEnrs(closestNodes, maxPayloadSize, enrOverhead)
|
||||||
portal_content_enrs_packed.observe(enrs.len().int64)
|
portal_content_enrs_packed.observe(enrs.len().int64)
|
||||||
|
|
||||||
@ -438,8 +436,8 @@ proc getInitialRadius(rc: RadiusConfig): UInt256 =
|
|||||||
# In case of a dynamic radius we start from the maximum value to quickly
|
# In case of a dynamic radius we start from the maximum value to quickly
|
||||||
# gather as much data as possible, and also make sure each data piece in
|
# gather as much data as possible, and also make sure each data piece in
|
||||||
# the database is in our range after a node restart.
|
# the database is in our range after a node restart.
|
||||||
# Alternative would be to store node the radius in database, and initialize it
|
# Alternative would be to store node the radius in database, and initialize
|
||||||
# from database after a restart
|
# it from database after a restart
|
||||||
return UInt256.high()
|
return UInt256.high()
|
||||||
|
|
||||||
proc new*(T: type PortalProtocol,
|
proc new*(T: type PortalProtocol,
|
||||||
@ -609,25 +607,20 @@ proc findContent*(p: PortalProtocol, dst: Node, contentKey: ByteList):
|
|||||||
return err("Trying to connect to node with unknown address")
|
return err("Trying to connect to node with unknown address")
|
||||||
|
|
||||||
# uTP protocol uses BE for all values in the header, incl. connection id
|
# uTP protocol uses BE for all values in the header, incl. connection id
|
||||||
let connectionResult =
|
let socket =
|
||||||
await p.stream.connectTo(
|
(await p.stream.connectTo(
|
||||||
nodeAddress.unsafeGet(),
|
nodeAddress.unsafeGet(),
|
||||||
uint16.fromBytesBE(m.connectionId)
|
uint16.fromBytesBE(m.connectionId)
|
||||||
)
|
)).valueOr:
|
||||||
|
debug "uTP connection error for find content", error
|
||||||
if connectionResult.isErr():
|
|
||||||
debug "uTP connection error while trying to find content",
|
|
||||||
error = connectionResult.error
|
|
||||||
return err("Error connecting uTP socket")
|
return err("Error connecting uTP socket")
|
||||||
|
|
||||||
let socket = connectionResult.get()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Read all bytes from the socket
|
# Read all bytes from the socket
|
||||||
# This will either end with a FIN, or because the read action times out.
|
# This will either end with a FIN, or because the read action times out.
|
||||||
# A FIN does not necessarily mean that the data read is complete. Further
|
# A FIN does not necessarily mean that the data read is complete.
|
||||||
# validation is required, using a length prefix here might be beneficial for
|
# Further validation is required, using a length prefix here might be
|
||||||
# this.
|
# beneficial for this.
|
||||||
let readFut = socket.read()
|
let readFut = socket.read()
|
||||||
|
|
||||||
readFut.cancelCallback = proc(udate: pointer) {.gcsafe.} =
|
readFut.cancelCallback = proc(udate: pointer) {.gcsafe.} =
|
||||||
@ -649,7 +642,7 @@ proc findContent*(p: PortalProtocol, dst: Node, contentKey: ByteList):
|
|||||||
else :
|
else :
|
||||||
debug "Socket read time-out",
|
debug "Socket read time-out",
|
||||||
socketKey = socket.socketKey
|
socketKey = socket.socketKey
|
||||||
# Note: This might look a bit strange, be not doing a socket.close()
|
# Note: This might look a bit strange, but not doing a socket.close()
|
||||||
# here as this is already done internally. utp_socket `checkTimeouts`
|
# here as this is already done internally. utp_socket `checkTimeouts`
|
||||||
# already does a socket.destroy() on timeout. Might want to change the
|
# already does a socket.destroy() on timeout. Might want to change the
|
||||||
# API on this later though.
|
# API on this later though.
|
||||||
@ -771,19 +764,14 @@ proc offer(p: PortalProtocol, o: OfferRequest):
|
|||||||
id = o.dst.id
|
id = o.dst.id
|
||||||
return err("Trying to connect to node with unknown address")
|
return err("Trying to connect to node with unknown address")
|
||||||
|
|
||||||
let connectionResult =
|
let socket =
|
||||||
await p.stream.connectTo(
|
(await p.stream.connectTo(
|
||||||
nodeAddress.unsafeGet(),
|
nodeAddress.unsafeGet(),
|
||||||
uint16.fromBytesBE(m.connectionId)
|
uint16.fromBytesBE(m.connectionId)
|
||||||
)
|
)).valueOr:
|
||||||
|
debug "uTP connection error for offer content", error
|
||||||
if connectionResult.isErr():
|
|
||||||
debug "Utp connection error while trying to offer content",
|
|
||||||
error = connectionResult.error
|
|
||||||
return err("Error connecting uTP socket")
|
return err("Error connecting uTP socket")
|
||||||
|
|
||||||
let socket = connectionResult.get()
|
|
||||||
|
|
||||||
template lenu32(x: untyped): untyped =
|
template lenu32(x: untyped): untyped =
|
||||||
uint32(len(x))
|
uint32(len(x))
|
||||||
|
|
||||||
@ -797,10 +785,8 @@ proc offer(p: PortalProtocol, o: OfferRequest):
|
|||||||
output.write(toBytes(content.lenu32, Leb128).toOpenArray())
|
output.write(toBytes(content.lenu32, Leb128).toOpenArray())
|
||||||
output.write(content)
|
output.write(content)
|
||||||
|
|
||||||
let dataWritten = await socket.write(output.getOutput)
|
let dataWritten = (await socket.write(output.getOutput)).valueOr:
|
||||||
if dataWritten.isErr:
|
debug "Error writing requested data", error
|
||||||
debug "Error writing requested data",
|
|
||||||
error = dataWritten.error
|
|
||||||
# No point in trying to continue writing data
|
# No point in trying to continue writing data
|
||||||
socket.close()
|
socket.close()
|
||||||
return err("Error writing requested data")
|
return err("Error writing requested data")
|
||||||
@ -825,10 +811,8 @@ proc offer(p: PortalProtocol, o: OfferRequest):
|
|||||||
# When data turns out missing, add a 0 size varint
|
# When data turns out missing, add a 0 size varint
|
||||||
output.write(toBytes(0'u8, Leb128).toOpenArray())
|
output.write(toBytes(0'u8, Leb128).toOpenArray())
|
||||||
|
|
||||||
let dataWritten = await socket.write(output.getOutput)
|
let dataWritten = (await socket.write(output.getOutput)).valueOr:
|
||||||
if dataWritten.isErr:
|
debug "Error writing requested data", error
|
||||||
debug "Error writing requested data",
|
|
||||||
error = dataWritten.error
|
|
||||||
# No point in trying to continue writing data
|
# No point in trying to continue writing data
|
||||||
socket.close()
|
socket.close()
|
||||||
return err("Error writing requested data")
|
return err("Error writing requested data")
|
||||||
@ -1143,12 +1127,9 @@ proc neighborhoodGossip*(
|
|||||||
|
|
||||||
# Just taking the first content item as target id.
|
# Just taking the first content item as target id.
|
||||||
# TODO: come up with something better?
|
# TODO: come up with something better?
|
||||||
let contentIdOpt = p.toContentId(contentList[0].contentKey)
|
let contentId = p.toContentId(contentList[0].contentKey).valueOr:
|
||||||
if contentIdOpt.isNone():
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
let contentId = contentIdOpt.get()
|
|
||||||
|
|
||||||
# For selecting the closest nodes to whom to gossip the content a mixed
|
# For selecting the closest nodes to whom to gossip the content a mixed
|
||||||
# approach is taken:
|
# approach is taken:
|
||||||
# 1. Select the closest neighbours in the routing table
|
# 1. Select the closest neighbours in the routing table
|
||||||
@ -1163,7 +1144,6 @@ proc neighborhoodGossip*(
|
|||||||
# in its propagation than when looking only for nodes in the own routing
|
# in its propagation than when looking only for nodes in the own routing
|
||||||
# table, but at the same time avoid unnecessary node lookups.
|
# table, but at the same time avoid unnecessary node lookups.
|
||||||
# It might still cause issues in data getting propagated in a wider id range.
|
# It might still cause issues in data getting propagated in a wider id range.
|
||||||
|
|
||||||
const maxGossipNodes = 8
|
const maxGossipNodes = 8
|
||||||
|
|
||||||
let closestLocalNodes = p.routingTable.neighbours(
|
let closestLocalNodes = p.routingTable.neighbours(
|
||||||
@ -1308,7 +1288,7 @@ proc stop*(p: PortalProtocol) =
|
|||||||
worker.cancel()
|
worker.cancel()
|
||||||
p.offerWorkers = @[]
|
p.offerWorkers = @[]
|
||||||
|
|
||||||
proc resolve*(p: PortalProtocol, id: NodeId): Future[Option[Node]] {.async.} =
|
proc resolve*(p: PortalProtocol, id: NodeId): Future[Opt[Node]] {.async.} =
|
||||||
## Resolve a `Node` based on provided `NodeId`.
|
## Resolve a `Node` based on provided `NodeId`.
|
||||||
##
|
##
|
||||||
## This will first look in the own routing table. If the node is known, it
|
## This will first look in the own routing table. If the node is known, it
|
||||||
@ -1316,14 +1296,14 @@ proc resolve*(p: PortalProtocol, id: NodeId): Future[Option[Node]] {.async.} =
|
|||||||
## does not reply, a lookup is done to see if it can find a (newer) record of
|
## does not reply, a lookup is done to see if it can find a (newer) record of
|
||||||
## the node on the network.
|
## the node on the network.
|
||||||
if id == p.localNode.id:
|
if id == p.localNode.id:
|
||||||
return some(p.localNode)
|
return Opt.some(p.localNode)
|
||||||
|
|
||||||
let node = p.routingTable.getNode(id)
|
let node = p.getNode(id)
|
||||||
if node.isSome():
|
if node.isSome():
|
||||||
let nodesMessage = await p.findNodes(node.get(), @[0'u16])
|
let nodesMessage = await p.findNodes(node.get(), @[0'u16])
|
||||||
# TODO: Handle failures better. E.g. stop on different failures than timeout
|
# TODO: Handle failures better. E.g. stop on different failures than timeout
|
||||||
if nodesMessage.isOk() and nodesMessage[].len > 0:
|
if nodesMessage.isOk() and nodesMessage[].len > 0:
|
||||||
return some(nodesMessage[][0])
|
return Opt.some(nodesMessage[][0])
|
||||||
|
|
||||||
let discovered = await p.lookup(id)
|
let discovered = await p.lookup(id)
|
||||||
for n in discovered:
|
for n in discovered:
|
||||||
@ -1331,11 +1311,12 @@ proc resolve*(p: PortalProtocol, id: NodeId): Future[Option[Node]] {.async.} =
|
|||||||
if node.isSome() and node.get().record.seqNum >= n.record.seqNum:
|
if node.isSome() and node.get().record.seqNum >= n.record.seqNum:
|
||||||
return node
|
return node
|
||||||
else:
|
else:
|
||||||
return some(n)
|
return Opt.some(n)
|
||||||
|
|
||||||
return node
|
return node
|
||||||
|
|
||||||
proc resolveWithRadius*(p: PortalProtocol, id: NodeId): Future[Option[(Node, UInt256)]] {.async.} =
|
proc resolveWithRadius*(
|
||||||
|
p: PortalProtocol, id: NodeId): Future[Opt[(Node, UInt256)]] {.async.} =
|
||||||
## Resolve a `Node` based on provided `NodeId`, also try to establish what
|
## Resolve a `Node` based on provided `NodeId`, also try to establish what
|
||||||
## is known radius of found node.
|
## is known radius of found node.
|
||||||
##
|
##
|
||||||
@ -1349,30 +1330,24 @@ proc resolveWithRadius*(p: PortalProtocol, id: NodeId): Future[Option[(Node, UIn
|
|||||||
##
|
##
|
||||||
|
|
||||||
let n = await p.resolve(id)
|
let n = await p.resolve(id)
|
||||||
|
|
||||||
if n.isNone():
|
if n.isNone():
|
||||||
return none((Node, UInt256))
|
return Opt.none((Node, UInt256))
|
||||||
|
|
||||||
let node = n.unsafeGet()
|
let node = n.unsafeGet()
|
||||||
|
|
||||||
let r = p.radiusCache.get(id)
|
let r = p.radiusCache.get(id)
|
||||||
|
|
||||||
if r.isSome():
|
if r.isSome():
|
||||||
return some((node, r.unsafeGet()))
|
return Opt.some((node, r.unsafeGet()))
|
||||||
|
|
||||||
let pongResult = await p.ping(node)
|
let pongResult = await p.ping(node)
|
||||||
|
|
||||||
if pongResult.isOk():
|
if pongResult.isOk():
|
||||||
let maybeRadius = p.radiusCache.get(id)
|
let maybeRadius = p.radiusCache.get(id)
|
||||||
|
# After successful ping radius should already be in cache, but for the
|
||||||
# After successful ping radius should already be in cache, but for the unlikely
|
# unlikely case that it is not, check it just to be sure.
|
||||||
# case that it is not, check it just to be sure.
|
# TODO: refactor ping to return node radius.
|
||||||
# TODO: rafactor ping to return node radius.
|
|
||||||
if maybeRadius.isNone():
|
if maybeRadius.isNone():
|
||||||
return none((Node, UInt256))
|
return Opt.none((Node, UInt256))
|
||||||
|
else:
|
||||||
# If pong is successful, radius of the node should definitly be in local
|
return Opt.some((node, maybeRadius.unsafeGet()))
|
||||||
# radius cache
|
|
||||||
return some((node, maybeRadius.unsafeGet()))
|
|
||||||
else:
|
else:
|
||||||
return none((Node, UInt256))
|
return Opt.none((Node, UInt256))
|
||||||
|
2
vendor/nim-eth
vendored
2
vendor/nim-eth
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 6b8a7b009eb94bfdac1410f243865984bdd7c4f2
|
Subproject commit 26ae539598e31efbaa016f6694b9a60ea08fc4b6
|
Loading…
x
Reference in New Issue
Block a user