mirror of https://github.com/status-im/nim-eth.git
Add discv5 constants to know allowed max talkresp message size (#732)
This commit is contained in:
parent
4eecab27ef
commit
aa1e738a97
|
@ -55,6 +55,22 @@ const
|
|||
# the UDP payload and the UDP header is not taken into account.
|
||||
# https://github.com/ethereum/devp2p/blob/26e380b1f3a57db16fbdd4528dde82104c77fa38/discv5/discv5-wire.md#udp-communication
|
||||
maxDiscv5PacketSize* = 1280
|
||||
# Following constants can be used to calculate the overhead of a packet and
|
||||
# thus the maximum size of a payload that can be sent over talkresp.
|
||||
discv5OrdinaryPacketOverhead* = # total 87 bytes
|
||||
16 + # IV size
|
||||
55 + # header size
|
||||
16 # HMAC
|
||||
# talkResp message = msgId + rlp: [request-id, response]
|
||||
discv5TalkRespOverhead* = # total 16 bytes
|
||||
1 + # talkResp msg id
|
||||
3 + # rlp encoding outer list, max length will be encoded in 2 bytes
|
||||
9 + # request id (max = 8) + 1 byte from rlp encoding byte string
|
||||
3 # rlp encoding response byte string, max length in 2 bytes
|
||||
# TalkResp message is a response message so the session is established and a
|
||||
# ordinary discv5 packet is used for size calculation.
|
||||
maxDiscv5TalkRespPayload* = maxDiscv5PacketSize - discv5OrdinaryPacketOverhead -
|
||||
discv5TalkRespOverhead
|
||||
|
||||
type
|
||||
AESGCMNonce* = array[gcmNonceSize, byte]
|
||||
|
|
|
@ -89,7 +89,7 @@ import
|
|||
ip_vote, nodes_verification]
|
||||
|
||||
export
|
||||
results, node, enr, encoding.maxDiscv5PacketSize
|
||||
results, node, enr, encoding.maxDiscv5PacketSize, encoding.maxDiscv5TalkRespPayload
|
||||
|
||||
declareCounter discovery_message_requests_outgoing,
|
||||
"Discovery protocol outgoing message requests", labels = ["response"]
|
||||
|
|
|
@ -158,6 +158,24 @@ suite "Discovery v5.1 Protocol Message Encodings":
|
|||
message.kind == talkResp
|
||||
message.talkResp.response == "hi".toBytes()
|
||||
|
||||
test "Talk Response Payload limit":
|
||||
let
|
||||
payload = repeat(5.byte, maxDiscv5TalkRespPayload)
|
||||
tr = TalkRespMessage(response: payload)
|
||||
reqId = RequestId(id: @[1.byte, 2, 3, 4, 5, 6, 7, 8]) # max requestId = 8 bytes
|
||||
|
||||
let encoded = encodeMessage(tr, reqId)
|
||||
check encoded.len() == maxDiscv5TalkRespPayload + discv5TalkRespOverhead
|
||||
|
||||
let decoded = decodeMessage(encoded)
|
||||
check decoded.isOk()
|
||||
|
||||
let message = decoded.get()
|
||||
check:
|
||||
message.reqId == reqId
|
||||
message.kind == talkResp
|
||||
message.talkResp.response == payload
|
||||
|
||||
test "Ping with too large RequestId":
|
||||
let
|
||||
enrSeq = 1'u64
|
||||
|
@ -626,3 +644,30 @@ suite "Discovery v5.1 Additional Encode/Decode":
|
|||
decoded.get().messageOpt.get().kind == ping
|
||||
decoded.get().messageOpt.get().ping.enrSeq == 0
|
||||
decoded[].requestNonce == nonce
|
||||
|
||||
test "Encode / Decode Ordinary Message Packet - TalkResp Payload limit":
|
||||
let
|
||||
payload = repeat(5.byte, maxDiscv5TalkRespPayload)
|
||||
m = TalkRespMessage(response: payload)
|
||||
reqId = RequestId.init(rng[])
|
||||
message = encodeMessage(m, reqId)
|
||||
|
||||
# Need to manually add the secrets that normally get negotiated in the
|
||||
# handshake packet.
|
||||
var secrets: HandshakeSecrets
|
||||
codecA.sessions.store(nodeB.id, nodeB.address.get(), secrets.recipientKey,
|
||||
secrets.initiatorKey)
|
||||
codecB.sessions.store(nodeA.id, nodeA.address.get(), secrets.initiatorKey,
|
||||
secrets.recipientKey)
|
||||
|
||||
let (data, nonce) = encodeMessagePacket(rng[], codecA, nodeB.id,
|
||||
nodeB.address.get(), message)
|
||||
|
||||
check data.len() == maxDiscv5PacketSize
|
||||
|
||||
let decoded = codecB.decodePacket(nodeA.address.get(), data)
|
||||
check:
|
||||
decoded.isOk()
|
||||
decoded[].flag == OrdinaryMessage
|
||||
decoded[].messageOpt.isSome()
|
||||
decoded[].requestNonce == nonce
|
||||
|
|
Loading…
Reference in New Issue