Add unittest for rlpx thunk payload tests

This commit is contained in:
kdeme 2019-10-22 14:08:25 +02:00 committed by zah
parent f5cdb916c0
commit 17f90920e0
5 changed files with 110 additions and 12 deletions

View File

@ -1,5 +1,5 @@
import import
endians, options, times, endians, options, times, chronicles,
stint, nimcrypto, eth/rlp, eth/trie/[trie_defs, db] stint, nimcrypto, eth/rlp, eth/trie/[trie_defs, db]
export export
@ -329,10 +329,7 @@ proc rlpHash*[T](v: T): Hash256 =
func blockHash*(h: BlockHeader): KeccakHash {.inline.} = rlpHash(h) func blockHash*(h: BlockHeader): KeccakHash {.inline.} = rlpHash(h)
proc notImplemented = proc notImplemented =
when defined(afl) or defined(libFuzzer): debug "Method not implemented"
discard
else:
doAssert false, "Method not implemented"
template hasData*(b: Blob): bool = b.len > 0 template hasData*(b: Blob): bool = b.len > 0
template hasData*(r: EthResourceRefs): bool = r != nil template hasData*(r: EthResourceRefs): bool = r != nil

View File

@ -3,12 +3,6 @@ import
eth/p2p/rlpx_protocols/[whisper_protocol, eth_protocol], eth/p2p/rlpx_protocols/[whisper_protocol, eth_protocol],
../fuzztest, ../p2p/p2p_test_helper ../fuzztest, ../p2p/p2p_test_helper
proc recvMsgMock(msg: openArray[byte]): tuple[msgId: int, msgData: Rlp] =
var rlp = rlpFromBytes(@msg.toRange)
let msgid = rlp.read(int)
return (msgId, rlp)
var var
node1: EthereumNode node1: EthereumNode
node2: EthereumNode node2: EthereumNode

View File

@ -1,5 +1,6 @@
import import
unittest, chronos, nimcrypto, eth/[keys, p2p], eth/p2p/[discovery, enode] unittest, chronos, nimcrypto, strutils,
eth/[keys, p2p], eth/p2p/[discovery, enode]
var nextPort = 30303 var nextPort = 30303
@ -39,3 +40,11 @@ proc packData*(payload: openArray[byte], pk: PrivateKey): seq[byte] =
signature = @(pk.signMessage(payload).getRaw()) signature = @(pk.signMessage(payload).getRaw())
msgHash = keccak256.digest(signature & payloadSeq) msgHash = keccak256.digest(signature & payloadSeq)
result = @(msgHash.data) & signature & payloadSeq result = @(msgHash.data) & signature & payloadSeq
template sourceDir*: string = currentSourcePath.rsplit(DirSep, 1)[0]
proc recvMsgMock*(msg: openArray[byte]): tuple[msgId: int, msgData: Rlp] =
var rlp = rlpFromBytes(@msg.toRange)
let msgid = rlp.read(int)
return (msgId, rlp)

View File

@ -0,0 +1,52 @@
{
"Invalid list when decoding for object": {
"payload": "03",
"error": "RlpTypeMismatch",
"description": "Object parameters are expected to be encoded in an RLP list"
},
"Message id that is not supported": {
"payload": "08",
"error": "UnsupportedMessageError",
"description": "This is a message id not used by devp2p, eth or whisper"
},
"Message id that is negative": {
"payload": "888888888888888888",
"error": "UnsupportedMessageError",
"description": "This payload will result in a negative number as message id"
},
"No Hash nor Status, but empty list": {
"payload": "20c1c0",
"error": "RlpTypeMismatch",
"description": "Decoding to HashOrStatus expects blob of size 1 or 32"
},
"No Hash nor Status, list instead of blob": {
"payload": "20c2c1c0",
"error": "RlpTypeMismatch",
"description": "Decoding to HashOrStatus expects blob of size 1 or 32"
},
"No Hash nor Status, blob of 2 bytes": {
"payload": "20c4c3820011",
"error": "RlpTypeMismatch",
"description": "Decoding to HashOrStatus expects blob of size 1 or 32"
},
"No Hash nor Status, blob of 33 bytes": {
"payload": "20e3e2a100112233445566778899aabbccddeeff00112233445566778899aabbcceeddff33",
"error": "RlpTypeMismatch",
"description": "Decoding to HashOrStatus expects blob of size 1 or 32"
},
"Listing elements when no data": {
"payload": "01e1",
"error": "MalformedRlpError",
"description": "listElem to error on empty list"
},
"Listing elements when invalid length": {
"payload": "01ffdada",
"error": "MalformedRlpError",
"description": "listElem to error on invalid size encoding"
},
"Listing elements when not a list": {
"payload": "010a",
"error": "RlpTypeMismatch",
"description": "listElem to assert on not a list"
}
}

View File

@ -0,0 +1,46 @@
import
json, os, stew/byteutils, unittest, chronos,
eth/p2p, eth/p2p/rlpx_protocols/[whisper_protocol, eth_protocol],
../p2p/p2p_test_helper
var
node1: EthereumNode
node2: EthereumNode
peer: Peer
node1 = setupTestNode(eth, Whisper)
node2 = setupTestNode(eth, Whisper)
node2.startListening()
peer = waitFor node1.rlpxConnect(newNode(initENode(node2.keys.pubKey,
node2.address)))
proc testPayloads(filename: string) =
let js = json.parseFile(filename)
suite extractFilename(filename):
for testname, testdata in js:
test testname:
let
payloadHex = testdata{"payload"}
error = testdata{"error"}
if payloadHex.isNil or payloadHex.kind != JString:
skip()
continue
if error.isNil or error.kind != JString:
skip()
continue
let payload = hexToSeqByte(payloadHex.str)
# TODO: can I convert the error string to an Exception type at runtime?
expect CatchableError:
try:
var (msgId, msgData) = recvMsgMock(payload)
waitFor peer.invokeThunk(msgId.int, msgData)
except CatchableError as e:
check: e.name == error.str
raise
testPayloads(sourceDir / "test_rlpx_thunk.json")