mirror of https://github.com/status-im/nim-eth.git
Limit request id to maximum 8 bytes
This commit is contained in:
parent
301067c869
commit
c28cba3589
|
@ -351,9 +351,8 @@ proc decodeMessage*(body: openarray[byte]): DecodeResult[Message] =
|
||||||
var rlp = rlpFromBytes(body.toOpenArray(1, body.high))
|
var rlp = rlpFromBytes(body.toOpenArray(1, body.high))
|
||||||
if rlp.enterList:
|
if rlp.enterList:
|
||||||
try:
|
try:
|
||||||
# TODO: 8 bytes limitation on RequestId decode.
|
|
||||||
message.reqId = rlp.read(RequestId)
|
message.reqId = rlp.read(RequestId)
|
||||||
except RlpError:
|
except RlpError, ValueError:
|
||||||
return err(PacketError)
|
return err(PacketError)
|
||||||
|
|
||||||
proc decode[T](rlp: var Rlp, v: var T)
|
proc decode[T](rlp: var Rlp, v: var T)
|
||||||
|
@ -556,9 +555,9 @@ proc decodePacket*(c: var Codec, fromAddr: Address, input: openArray[byte]):
|
||||||
input.toOpenArray(ivSize + header.len, input.high))
|
input.toOpenArray(ivSize + header.len, input.high))
|
||||||
|
|
||||||
proc init*(T: type RequestId, rng: var BrHmacDrbgContext): T =
|
proc init*(T: type RequestId, rng: var BrHmacDrbgContext): T =
|
||||||
var id = newSeq[byte](8) # RequestId must be <= 8 bytes
|
var reqId = RequestId(id: newSeq[byte](8)) # RequestId must be <= 8 bytes
|
||||||
brHmacDrbgGenerate(rng, id)
|
brHmacDrbgGenerate(rng, reqId.id)
|
||||||
id
|
reqId
|
||||||
|
|
||||||
proc numFields(T: typedesc): int =
|
proc numFields(T: typedesc): int =
|
||||||
for k, v in fieldPairs(default(T)): inc result
|
for k, v in fieldPairs(default(T)): inc result
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import
|
import
|
||||||
std/hashes,
|
std/hashes,
|
||||||
stint,
|
stint,
|
||||||
enr, node
|
eth/rlp, enr, node
|
||||||
|
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
|
@ -32,7 +32,8 @@ type
|
||||||
regconfirmation = 0x09
|
regconfirmation = 0x09
|
||||||
topicquery = 0x0A
|
topicquery = 0x0A
|
||||||
|
|
||||||
RequestId* = seq[byte]
|
RequestId* = object
|
||||||
|
id*: seq[byte]
|
||||||
|
|
||||||
PingMessage* = object
|
PingMessage* = object
|
||||||
enrSeq*: uint64
|
enrSeq*: uint64
|
||||||
|
@ -99,6 +100,23 @@ template messageKind*(T: typedesc[SomeMessage]): MessageKind =
|
||||||
elif T is TalkReqMessage: talkreq
|
elif T is TalkReqMessage: talkreq
|
||||||
elif T is TalkRespMessage: talkresp
|
elif T is TalkRespMessage: talkresp
|
||||||
|
|
||||||
|
proc read*(rlp: var Rlp, T: type RequestId): T
|
||||||
|
{.raises: [ValueError, RlpError, Defect].} =
|
||||||
|
mixin read
|
||||||
|
var reqId: RequestId
|
||||||
|
reqId.id = rlp.toBytes()
|
||||||
|
if reqId.id.len > 8:
|
||||||
|
raise newException(ValueError, "RequestId is > 8 bytes")
|
||||||
|
rlp.skipElem()
|
||||||
|
|
||||||
|
reqId
|
||||||
|
|
||||||
|
proc append*(writer: var RlpWriter, value: RequestId) =
|
||||||
|
writer.append(value.id)
|
||||||
|
|
||||||
|
proc hash*(reqId: RequestId): Hash =
|
||||||
|
hash(reqId.id)
|
||||||
|
|
||||||
proc toBytes*(id: NodeId): array[32, byte] {.inline.} =
|
proc toBytes*(id: NodeId): array[32, byte] {.inline.} =
|
||||||
id.toByteArrayBE()
|
id.toByteArrayBE()
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ suite "Discovery v5.1 Protocol Message Encodings":
|
||||||
let
|
let
|
||||||
enrSeq = 1'u64
|
enrSeq = 1'u64
|
||||||
p = PingMessage(enrSeq: enrSeq)
|
p = PingMessage(enrSeq: enrSeq)
|
||||||
reqId: RequestId = @[1.byte]
|
reqId = RequestId(id: @[1.byte])
|
||||||
|
|
||||||
let encoded = encodeMessage(p, reqId)
|
let encoded = encodeMessage(p, reqId)
|
||||||
check encoded.toHex == "01c20101"
|
check encoded.toHex == "01c20101"
|
||||||
|
@ -31,7 +31,7 @@ suite "Discovery v5.1 Protocol Message Encodings":
|
||||||
ip = @[127.byte, 0, 0, 1]
|
ip = @[127.byte, 0, 0, 1]
|
||||||
port = 5000'u16
|
port = 5000'u16
|
||||||
p = PongMessage(enrSeq: enrSeq, ip: ip, port: port)
|
p = PongMessage(enrSeq: enrSeq, ip: ip, port: port)
|
||||||
reqId: RequestId = @[1.byte]
|
reqId = RequestId(id: @[1.byte])
|
||||||
|
|
||||||
let encoded = encodeMessage(p, reqId)
|
let encoded = encodeMessage(p, reqId)
|
||||||
check encoded.toHex == "02ca0101847f000001821388"
|
check encoded.toHex == "02ca0101847f000001821388"
|
||||||
|
@ -51,7 +51,7 @@ suite "Discovery v5.1 Protocol Message Encodings":
|
||||||
let
|
let
|
||||||
distances = @[0x0100'u32]
|
distances = @[0x0100'u32]
|
||||||
fn = FindNodeMessage(distances: distances)
|
fn = FindNodeMessage(distances: distances)
|
||||||
reqId: RequestId = @[1.byte]
|
reqId = RequestId(id: @[1.byte])
|
||||||
|
|
||||||
let encoded = encodeMessage(fn, reqId)
|
let encoded = encodeMessage(fn, reqId)
|
||||||
check encoded.toHex == "03c501c3820100"
|
check encoded.toHex == "03c501c3820100"
|
||||||
|
@ -69,7 +69,7 @@ suite "Discovery v5.1 Protocol Message Encodings":
|
||||||
let
|
let
|
||||||
total = 0x1'u32
|
total = 0x1'u32
|
||||||
n = NodesMessage(total: total)
|
n = NodesMessage(total: total)
|
||||||
reqId: RequestId = @[1.byte]
|
reqId = RequestId(id: @[1.byte])
|
||||||
|
|
||||||
let encoded = encodeMessage(n, reqId)
|
let encoded = encodeMessage(n, reqId)
|
||||||
check encoded.toHex == "04c30101c0"
|
check encoded.toHex == "04c30101c0"
|
||||||
|
@ -91,7 +91,7 @@ suite "Discovery v5.1 Protocol Message Encodings":
|
||||||
let
|
let
|
||||||
total = 0x1'u32
|
total = 0x1'u32
|
||||||
n = NodesMessage(total: total, enrs: @[e1, e2])
|
n = NodesMessage(total: total, enrs: @[e1, e2])
|
||||||
reqId: RequestId = @[1.byte]
|
reqId = RequestId(id: @[1.byte])
|
||||||
|
|
||||||
let encoded = encodeMessage(n, reqId)
|
let encoded = encodeMessage(n, reqId)
|
||||||
check encoded.toHex == "04f8f20101f8eef875b8401ce2991c64993d7c84c29a00bdc871917551c7d330fca2dd0d69c706596dc655448f030b98a77d4001fd46ae0112ce26d613c5a6a02a81a6223cd0c4edaa53280182696482763489736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138f875b840d7f1c39e376297f81d7297758c64cb37dcc5c3beea9f57f7ce9695d7d5a67553417d719539d6ae4b445946de4d99e680eb8063f29485b555d45b7df16a1850130182696482763489736563703235366b31a1030e2cb74241c0c4fc8e8166f1a79a05d5b0dd95813a74b094529f317d5c39d235"
|
check encoded.toHex == "04f8f20101f8eef875b8401ce2991c64993d7c84c29a00bdc871917551c7d330fca2dd0d69c706596dc655448f030b98a77d4001fd46ae0112ce26d613c5a6a02a81a6223cd0c4edaa53280182696482763489736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138f875b840d7f1c39e376297f81d7297758c64cb37dcc5c3beea9f57f7ce9695d7d5a67553417d719539d6ae4b445946de4d99e680eb8063f29485b555d45b7df16a1850130182696482763489736563703235366b31a1030e2cb74241c0c4fc8e8166f1a79a05d5b0dd95813a74b094529f317d5c39d235"
|
||||||
|
@ -108,6 +108,18 @@ suite "Discovery v5.1 Protocol Message Encodings":
|
||||||
message.nodes.enrs[0] == e1
|
message.nodes.enrs[0] == e1
|
||||||
message.nodes.enrs[1] == e2
|
message.nodes.enrs[1] == e2
|
||||||
|
|
||||||
|
test "Ping with too large RequestId":
|
||||||
|
let
|
||||||
|
enrSeq = 1'u64
|
||||||
|
p = PingMessage(enrSeq: enrSeq)
|
||||||
|
# 1 byte too large
|
||||||
|
reqId = RequestId(id: @[0.byte, 1, 2, 3, 4, 5, 6, 7, 8])
|
||||||
|
let encoded = encodeMessage(p, reqId)
|
||||||
|
check encoded.toHex == "01cb8900010203040506070801"
|
||||||
|
|
||||||
|
let decoded = decodeMessage(encoded)
|
||||||
|
check decoded.isErr()
|
||||||
|
|
||||||
# According to test vectors:
|
# According to test vectors:
|
||||||
# https://github.com/fjl/devp2p/blob/discv5-v1-update/discv5/discv5-wire-test-vectors.md#cryptographic-primitives
|
# https://github.com/fjl/devp2p/blob/discv5-v1-update/discv5/discv5-wire-test-vectors.md#cryptographic-primitives
|
||||||
suite "Discovery v5.1 Cryptographic Primitives Test Vectors":
|
suite "Discovery v5.1 Cryptographic Primitives Test Vectors":
|
||||||
|
@ -236,7 +248,7 @@ suite "Discovery v5.1 Packet Encodings Test Vectors":
|
||||||
check:
|
check:
|
||||||
decoded.isOK()
|
decoded.isOK()
|
||||||
decoded.get().messageOpt.isSome()
|
decoded.get().messageOpt.isSome()
|
||||||
decoded.get().messageOpt.get().reqId == hexToSeqByte(pingReqId)
|
decoded.get().messageOpt.get().reqId.id == hexToSeqByte(pingReqId)
|
||||||
decoded.get().messageOpt.get().kind == ping
|
decoded.get().messageOpt.get().kind == ping
|
||||||
decoded.get().messageOpt.get().ping.enrSeq == pingEnrSeq
|
decoded.get().messageOpt.get().ping.enrSeq == pingEnrSeq
|
||||||
|
|
||||||
|
@ -300,7 +312,7 @@ suite "Discovery v5.1 Packet Encodings Test Vectors":
|
||||||
|
|
||||||
check:
|
check:
|
||||||
decoded.isOk()
|
decoded.isOk()
|
||||||
decoded.get().message.reqId == hexToSeqByte(pingReqId)
|
decoded.get().message.reqId.id == hexToSeqByte(pingReqId)
|
||||||
decoded.get().message.kind == ping
|
decoded.get().message.kind == ping
|
||||||
decoded.get().message.ping.enrSeq == pingEnrSeq
|
decoded.get().message.ping.enrSeq == pingEnrSeq
|
||||||
decoded.get().node.isNone()
|
decoded.get().node.isNone()
|
||||||
|
@ -347,7 +359,7 @@ suite "Discovery v5.1 Packet Encodings Test Vectors":
|
||||||
|
|
||||||
check:
|
check:
|
||||||
decoded.isOk()
|
decoded.isOk()
|
||||||
decoded.get().message.reqId == hexToSeqByte(pingReqId)
|
decoded.get().message.reqId.id == hexToSeqByte(pingReqId)
|
||||||
decoded.get().message.kind == ping
|
decoded.get().message.kind == ping
|
||||||
decoded.get().message.ping.enrSeq == pingEnrSeq
|
decoded.get().message.ping.enrSeq == pingEnrSeq
|
||||||
decoded.get().node.isSome()
|
decoded.get().node.isSome()
|
||||||
|
|
Loading…
Reference in New Issue