mirror of https://github.com/status-im/nim-eth.git
Build fuzzing tests in CI and fix current fuzzing tests (#396)
* Build fuzzing tests in CI and fix current fuzzing tests * Build fuzzing tests separately (fix Windows CI)
This commit is contained in:
parent
bea1f1c6a1
commit
df6020832b
|
@ -237,3 +237,4 @@ jobs:
|
||||||
nimble install -y --depsOnly
|
nimble install -y --depsOnly
|
||||||
nimble test
|
nimble test
|
||||||
nimble build_dcli
|
nimble build_dcli
|
||||||
|
nimble build_fuzzers
|
||||||
|
|
13
eth.nimble
13
eth.nimble
|
@ -90,3 +90,16 @@ task test_discv5_full, "Run discovery v5 and its dependencies tests":
|
||||||
|
|
||||||
task build_dcli, "Build dcli":
|
task build_dcli, "Build dcli":
|
||||||
buildBinary("eth/p2p/discoveryv5/dcli")
|
buildBinary("eth/p2p/discoveryv5/dcli")
|
||||||
|
|
||||||
|
import os, strutils
|
||||||
|
|
||||||
|
task build_fuzzers, "Build fuzzer test cases":
|
||||||
|
# This file is there to be able to quickly build the fuzzer test cases in
|
||||||
|
# order to avoid bit rot (e.g. for CI). Not for actual fuzzing.
|
||||||
|
# TODO: Building fuzzer test case one by one will make it take a bit longer,
|
||||||
|
# but we cannot import them in one Nim file due to the usage of
|
||||||
|
# `exportc: "AFLmain"` in the fuzzing test template for Windows:
|
||||||
|
# https://github.com/status-im/nim-testutils/blob/master/testutils/fuzzing.nim#L100
|
||||||
|
for file in walkDirRec("tests/fuzzing/"):
|
||||||
|
if file.endsWith("nim"):
|
||||||
|
buildBinary(file)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
import
|
import
|
||||||
eth/common/[eth_types, state_accessors]
|
../common/[eth_types, state_accessors]
|
||||||
|
|
||||||
# TODO: Perhaps we can move this to eth-common
|
# TODO: Perhaps we can move this to eth-common
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
import
|
import
|
||||||
testutils/fuzzing, chronicles,
|
testutils/fuzzing, chronicles, nimcrypto/keccak,
|
||||||
eth/p2p/[discovery, enode], eth/[keys, rlp],
|
../../../eth/p2p/[discovery, enode], ../../../eth/[keys, rlp],
|
||||||
../../p2p/p2p_test_helper
|
../../p2p/p2p_test_helper
|
||||||
|
|
||||||
const DefaultListeningPort = 30303
|
const DefaultListeningPort = 30303
|
||||||
var targetNode: DiscoveryProtocol
|
var targetNode: DiscoveryProtocol
|
||||||
|
|
||||||
|
proc packData(payload: openArray[byte], pk: PrivateKey): seq[byte] =
|
||||||
|
let
|
||||||
|
payloadSeq = @payload
|
||||||
|
signature = @(pk.sign(payload).toRaw())
|
||||||
|
msgHash = keccak256.digest(signature & payloadSeq)
|
||||||
|
result = @(msgHash.data) & signature & payloadSeq
|
||||||
|
|
||||||
init:
|
init:
|
||||||
# Set up a discovery node, this is the node we target when fuzzing
|
# Set up a discovery node, this is the node we target when fuzzing
|
||||||
var
|
var
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
import
|
import
|
||||||
chronos, times, stew/byteutils, stint, chronicles, streams, nimcrypto, os,
|
std/[times, os, strformat, strutils],
|
||||||
strformat, strutils, eth/p2p/[discovery, kademlia], eth/[keys, rlp],
|
chronos, stew/byteutils, stint, chronicles, nimcrypto,
|
||||||
../../p2p/p2p_test_helper
|
../../../eth/p2p/[discovery, kademlia], ../../../eth/[keys, rlp],
|
||||||
|
../../p2p/p2p_test_helper,
|
||||||
|
../fuzzing_helpers
|
||||||
|
|
||||||
template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0]
|
template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0]
|
||||||
const inputsDir = &"{sourceDir}{DirSep}generated-input{DirSep}"
|
const inputsDir = &"{sourceDir}{DirSep}generated-input{DirSep}"
|
||||||
|
|
||||||
proc toFile(data: Bytes, fn: string) =
|
|
||||||
var s = newFileStream(fn, fmWrite)
|
|
||||||
for x in data:
|
|
||||||
s.write(x)
|
|
||||||
s.close()
|
|
||||||
|
|
||||||
const EXPIRATION = 3600 * 24 * 365 * 10
|
const EXPIRATION = 3600 * 24 * 365 * 10
|
||||||
proc expiration(): uint32 = uint32(epochTime() + EXPIRATION)
|
proc expiration(): uint32 = uint32(epochTime() + EXPIRATION)
|
||||||
|
|
||||||
|
@ -32,7 +28,7 @@ proc generate() =
|
||||||
|
|
||||||
# valid data for a Pong packet
|
# valid data for a Pong packet
|
||||||
block:
|
block:
|
||||||
let token = keccak256.digest(@[0])
|
let token = keccak256.digest(@[byte 0])
|
||||||
let payload = rlp.encode((toAddr, token , expiration()))
|
let payload = rlp.encode((toAddr, token , expiration()))
|
||||||
let encodedData = @[2.byte] & payload
|
let encodedData = @[2.byte] & payload
|
||||||
debug "Pong", data=byteutils.toHex(encodedData)
|
debug "Pong", data=byteutils.toHex(encodedData)
|
||||||
|
@ -42,9 +38,9 @@ proc generate() =
|
||||||
# valid data for a FindNode packet
|
# valid data for a FindNode packet
|
||||||
block:
|
block:
|
||||||
var data: array[64, byte]
|
var data: array[64, byte]
|
||||||
data[32 .. ^1] = peerKey.toPublicKey().tryGet().toNodeId().toByteArrayBE()
|
data[32 .. ^1] = peerKey.toPublicKey().toNodeId().toByteArrayBE()
|
||||||
let payload = rlp.encode((data, expiration()))
|
let payload = rlp.encode((data, expiration()))
|
||||||
let encodedData = @[3.byte] & payload.toSeq()
|
let encodedData = @[3.byte] & @payload
|
||||||
debug "FindNode", data=byteutils.toHex(encodedData)
|
debug "FindNode", data=byteutils.toHex(encodedData)
|
||||||
|
|
||||||
encodedData.toFile(inputsDir & "findnode")
|
encodedData.toFile(inputsDir & "findnode")
|
||||||
|
@ -62,11 +58,11 @@ proc generate() =
|
||||||
type Neighbour = tuple[ip: IpAddress, udpPort, tcpPort: Port, pk: PublicKey]
|
type Neighbour = tuple[ip: IpAddress, udpPort, tcpPort: Port, pk: PublicKey]
|
||||||
var nodes = newSeqOfCap[Neighbour](2)
|
var nodes = newSeqOfCap[Neighbour](2)
|
||||||
|
|
||||||
nodes.add((n1Addr.ip, n1Addr.udpPort, n1Addr.tcpPort, n1Key.toPublicKey().tryGet()))
|
nodes.add((n1Addr.ip, n1Addr.udpPort, n1Addr.tcpPort, n1Key.toPublicKey()))
|
||||||
nodes.add((n2Addr.ip, n2Addr.udpPort, n2Addr.tcpPort, n2Key.toPublicKey().tryGet()))
|
nodes.add((n2Addr.ip, n2Addr.udpPort, n2Addr.tcpPort, n2Key.toPublicKey()))
|
||||||
|
|
||||||
let payload = rlp.encode((nodes, expiration()))
|
let payload = rlp.encode((nodes, expiration()))
|
||||||
let encodedData = @[4.byte] & payload.toSeq()
|
let encodedData = @[4.byte] & @payload
|
||||||
debug "Neighbours", data=byteutils.toHex(encodedData)
|
debug "Neighbours", data=byteutils.toHex(encodedData)
|
||||||
|
|
||||||
encodedData.toFile(inputsDir & "neighbours")
|
encodedData.toFile(inputsDir & "neighbours")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
testutils/fuzzing, stew/byteutils,
|
testutils/fuzzing,
|
||||||
eth/rlp, eth/p2p/discoveryv5/[encoding, messages]
|
../../../eth/rlp, ../../../eth/p2p/discoveryv5/[encoding, messages]
|
||||||
|
|
||||||
test:
|
test:
|
||||||
block:
|
block:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
testutils/fuzzing, stew/shims/net, stew/byteutils,
|
testutils/fuzzing, stew/shims/net,
|
||||||
eth/p2p/discoveryv5/[encoding, enr, sessions, node]
|
../../../eth/p2p/discoveryv5/[encoding, enr, sessions, node]
|
||||||
|
|
||||||
init:
|
init:
|
||||||
const
|
const
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
testutils/fuzzing, stew/byteutils,
|
testutils/fuzzing, stew/byteutils,
|
||||||
eth/rlp, eth/p2p/discoveryv5/enr
|
../../../eth/rlp, ../../../eth/p2p/discoveryv5/enr
|
||||||
|
|
||||||
test:
|
test:
|
||||||
block:
|
block:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import
|
import
|
||||||
std/[os, strutils, options],
|
std/[os, strutils, options],
|
||||||
stew/shims/net,
|
stew/shims/net,
|
||||||
eth/keys, eth/p2p/discoveryv5/enr,
|
../../../eth/keys, ../../../eth/p2p/discoveryv5/enr,
|
||||||
../fuzzing_helpers
|
../fuzzing_helpers
|
||||||
|
|
||||||
template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0]
|
template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0]
|
||||||
|
@ -12,7 +12,7 @@ proc generate() =
|
||||||
rng = newRng()
|
rng = newRng()
|
||||||
privKey = PrivateKey.random(rng[])
|
privKey = PrivateKey.random(rng[])
|
||||||
ip = some(ValidIpAddress.init("127.0.0.1"))
|
ip = some(ValidIpAddress.init("127.0.0.1"))
|
||||||
port = Port(20301)
|
port = some(Port(20301))
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let record = enr.Record.init(1, privKey, ip, port, port)[]
|
let record = enr.Record.init(1, privKey, ip, port, port)[]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import
|
import
|
||||||
std/streams
|
std/streams
|
||||||
|
|
||||||
proc toFile*(data: seq[byte], fn: string) =
|
proc toFile*(data: seq[byte], fn: string) =
|
||||||
var s = newFileStream(fn, fmWrite)
|
var s = newFileStream(fn, fmWrite)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
testutils/fuzzing, chronicles,
|
testutils/fuzzing, chronicles,
|
||||||
eth/rlp
|
../../../eth/rlp
|
||||||
|
|
||||||
type
|
type
|
||||||
TestEnum = enum
|
TestEnum = enum
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
testutils/fuzzing, chronicles,
|
testutils/fuzzing, chronicles,
|
||||||
eth/rlp
|
../../../eth/rlp
|
||||||
|
|
||||||
test:
|
test:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import
|
import
|
||||||
testutils/fuzzing, chronos,
|
testutils/fuzzing, chronos,
|
||||||
eth/p2p, eth/p2p/rlpx, eth/p2p/private/p2p_types,
|
../../../eth/p2p, ../../../eth/p2p/rlpx, ../../../eth/p2p/private/p2p_types,
|
||||||
eth/p2p/rlpx_protocols/[whisper_protocol, eth_protocol],
|
../../../eth/p2p/rlpx_protocols/[whisper_protocol, eth_protocol],
|
||||||
../p2p/p2p_test_helper
|
../../p2p/p2p_test_helper
|
||||||
|
|
||||||
var
|
var
|
||||||
node1: EthereumNode
|
node1: EthereumNode
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import
|
import
|
||||||
options, sequtils, chronicles,
|
std/[options, sequtils],
|
||||||
eth/p2p/rlpx_protocols/whisper_protocol as whisper,
|
chronicles, testutils/fuzzing,
|
||||||
../fuzztest
|
../../../eth/p2p/rlpx_protocols/whisper_protocol as whisper,
|
||||||
|
../../../eth/keys
|
||||||
|
|
||||||
test:
|
test:
|
||||||
let
|
let
|
||||||
|
rng = newRng()
|
||||||
data = @payload.distribute(2)
|
data = @payload.distribute(2)
|
||||||
whisperPayload = Payload(payload: data[0], padding: some(data[1]))
|
whisperPayload = Payload(payload: data[0], padding: some(data[1]))
|
||||||
encoded = whisper.encode(whisperPayload)
|
encoded = whisper.encode(rng[], whisperPayload)
|
||||||
|
|
||||||
decoded = whisper.decode(encoded.get())
|
decoded = whisper.decode(encoded.get())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue