mirror of https://github.com/status-im/nim-eth.git
Remove unused mock_peers and tserver files (#540)
This commit is contained in:
parent
4c821c5eae
commit
3e44299b49
|
@ -1,217 +0,0 @@
|
||||||
import
|
|
||||||
std/[macros, deques, algorithm],
|
|
||||||
chronos,
|
|
||||||
".."/[keys, rlp, p2p], ../common/eth_types,
|
|
||||||
./private/p2p_types, ./rlpx
|
|
||||||
|
|
||||||
type
|
|
||||||
Action = proc (p: Peer, data: Rlp): Future[void] {.gcsafe.}
|
|
||||||
|
|
||||||
ProtocolMessagePair = object
|
|
||||||
protocol: ProtocolInfo
|
|
||||||
id: int
|
|
||||||
|
|
||||||
ExpectedMsg = object
|
|
||||||
msg: ProtocolMessagePair
|
|
||||||
response: Action
|
|
||||||
|
|
||||||
MockConf* = ref object
|
|
||||||
keys*: KeyPair
|
|
||||||
address*: Address
|
|
||||||
networkId*: uint
|
|
||||||
chain*: AbstractChainDB
|
|
||||||
clientId*: string
|
|
||||||
waitForHello*: bool
|
|
||||||
|
|
||||||
devp2pHandshake: ExpectedMsg
|
|
||||||
handshakes: seq[ExpectedMsg]
|
|
||||||
protocols: seq[ProtocolInfo]
|
|
||||||
|
|
||||||
expectedMsgs: Deque[ExpectedMsg]
|
|
||||||
receivedMsgsCount: int
|
|
||||||
when useSnappy:
|
|
||||||
useCompression*: bool
|
|
||||||
|
|
||||||
var
|
|
||||||
nextUnusedMockPort = 40304
|
|
||||||
|
|
||||||
proc toAction(a: Action): Action = a
|
|
||||||
|
|
||||||
proc toAction[N](actions: array[N, Action]): Action =
|
|
||||||
mixin await
|
|
||||||
result = proc (peer: Peer, data: Rlp) {.async.} =
|
|
||||||
for a in actions:
|
|
||||||
await a(peer, data)
|
|
||||||
|
|
||||||
proc toAction(a: proc (): Future[void]): Action =
|
|
||||||
result = proc (peer: Peer, data: Rlp) {.async.} =
|
|
||||||
await a()
|
|
||||||
|
|
||||||
proc toAction(a: proc (peer: Peer): Future[void]): Action =
|
|
||||||
result = proc (peer: Peer, data: Rlp) {.async.} =
|
|
||||||
await a(peer)
|
|
||||||
|
|
||||||
proc delay*(duration: int): Action =
|
|
||||||
result = proc (p: Peer, data: Rlp) {.async.} =
|
|
||||||
await sleepAsync(duration)
|
|
||||||
|
|
||||||
proc reply(bytes: Bytes): Action =
|
|
||||||
result = proc (p: Peer, data: Rlp) {.async.} =
|
|
||||||
await p.sendMsg(bytes)
|
|
||||||
|
|
||||||
proc reply*[Msg](msg: Msg): Action =
|
|
||||||
mixin await
|
|
||||||
result = proc (p: Peer, data: Rlp) {.async.} =
|
|
||||||
await p.send(msg)
|
|
||||||
|
|
||||||
proc localhostAddress*(port: int): Address =
|
|
||||||
let port = Port(port)
|
|
||||||
result = Address(udpPort: port, tcpPort: port, ip: parseIpAddress("127.0.0.1"))
|
|
||||||
|
|
||||||
proc makeProtoMsgPair(MsgType: type): ProtocolMessagePair =
|
|
||||||
mixin msgProtocol, protocolInfo
|
|
||||||
result.protocol = MsgType.msgProtocol.protocolInfo
|
|
||||||
result.id = MsgType.msgId
|
|
||||||
|
|
||||||
proc readReqId*(rlp: Rlp): int =
|
|
||||||
var r = rlp
|
|
||||||
return r.read(int)
|
|
||||||
|
|
||||||
proc expectationViolationMsg(mock: MockConf,
|
|
||||||
reason: string,
|
|
||||||
receivedMsg: ptr MessageInfo): string =
|
|
||||||
result = "[Mock expectation violated] " & reason & ": " & receivedMsg.name
|
|
||||||
for i in 0 ..< mock.expectedMsgs.len:
|
|
||||||
let expected = mock.expectedMsgs[i].msg
|
|
||||||
result.add "\n " & expected.protocol.messages[expected.id].name
|
|
||||||
if i == mock.receivedMsgsCount: result.add " <- we are here"
|
|
||||||
result.add "\n"
|
|
||||||
|
|
||||||
proc addProtocol(mock: MockConf, p: ProtocolInfo): ProtocolInfo =
|
|
||||||
result = create ProtocolInfoObj
|
|
||||||
deepCopy(result[], p[])
|
|
||||||
|
|
||||||
proc incomingMsgHandler(p: Peer, receivedMsgId: int, rlp: Rlp): Future[void] {.gcsafe.} =
|
|
||||||
let (receivedMsgProto, receivedMsgInfo) = p.getMsgMetadata(receivedMsgId)
|
|
||||||
let expectedMsgIdx = mock.receivedMsgsCount
|
|
||||||
|
|
||||||
template fail(reason: string) =
|
|
||||||
stdout.write mock.expectationViolationMsg(reason, receivedMsgInfo)
|
|
||||||
quit 1
|
|
||||||
|
|
||||||
if expectedMsgIdx > mock.expectedMsgs.len:
|
|
||||||
fail "Mock peer received more messages than expected"
|
|
||||||
|
|
||||||
let expectedMsg = mock.expectedMsgs[expectedMsgIdx]
|
|
||||||
if receivedMsgInfo.id != expectedMsg.msg.id or
|
|
||||||
receivedMsgProto.name != expectedMsg.msg.protocol.name:
|
|
||||||
fail "Mock peer received an unexpected message"
|
|
||||||
|
|
||||||
inc mock.receivedMsgsCount
|
|
||||||
if expectedMsg.response != nil:
|
|
||||||
return expectedMsg.response(p, rlp)
|
|
||||||
else:
|
|
||||||
result = newFuture[void]()
|
|
||||||
result.complete()
|
|
||||||
|
|
||||||
for m in mitems(result.messages):
|
|
||||||
m.thunk = incomingMsgHandler
|
|
||||||
|
|
||||||
result.handshake = nil
|
|
||||||
|
|
||||||
# TODO This mock conf can override this
|
|
||||||
result.disconnectHandler = nil
|
|
||||||
|
|
||||||
mock.protocols.add result
|
|
||||||
|
|
||||||
proc addHandshake*(mock: MockConf, msg: auto) =
|
|
||||||
var msgInfo = makeProtoMsgPair(msg.type)
|
|
||||||
msgInfo.protocol = mock.addProtocol(msgInfo.protocol)
|
|
||||||
let expectedMsg = ExpectedMsg(msg: msgInfo, response: reply(msg))
|
|
||||||
|
|
||||||
when msg is DevP2P.hello:
|
|
||||||
devp2pHandshake = expectedMsg
|
|
||||||
else:
|
|
||||||
mock.handshakes.add expectedMsg
|
|
||||||
|
|
||||||
proc addCapability*(mock: MockConf, Protocol: type) =
|
|
||||||
mixin defaultTestingHandshake, protocolInfo
|
|
||||||
|
|
||||||
when compiles(defaultTestingHandshake(Protocol)):
|
|
||||||
mock.addHandshake(defaultTestingHandshake(Protocol))
|
|
||||||
else:
|
|
||||||
discard mock.addProtocol(Protocol.protocolInfo)
|
|
||||||
|
|
||||||
proc expectImpl(mock: MockConf, msg: ProtocolMessagePair, action: Action) =
|
|
||||||
mock.expectedMsgs.addLast ExpectedMsg(msg: msg, response: action)
|
|
||||||
|
|
||||||
macro expect*(mock: MockConf, MsgType: type, handler: untyped = nil): untyped =
|
|
||||||
if handler.kind in {nnkLambda, nnkDo}:
|
|
||||||
handler.addPragma ident("async")
|
|
||||||
|
|
||||||
result = newCall(
|
|
||||||
bindSym("expectImpl"),
|
|
||||||
mock,
|
|
||||||
newCall(bindSym"makeProtoMsgPair", MsgType.getType),
|
|
||||||
newCall(bindSym"toAction", handler))
|
|
||||||
|
|
||||||
template compression(m: MockConf): bool =
|
|
||||||
when useSnappy:
|
|
||||||
m.useCompression
|
|
||||||
else:
|
|
||||||
false
|
|
||||||
|
|
||||||
proc newMockPeer*(userConfigurator: proc (m: MockConf)): EthereumNode =
|
|
||||||
var mockConf = new MockConf
|
|
||||||
mockConf.keys = KeyPair.random()[]
|
|
||||||
mockConf.address = localhostAddress(nextUnusedMockPort)
|
|
||||||
inc nextUnusedMockPort
|
|
||||||
mockConf.networkId = 1'u
|
|
||||||
mockConf.clientId = "Mock Peer"
|
|
||||||
mockConf.waitForHello = true
|
|
||||||
mockConf.expectedMsgs = initDeque[ExpectedMsg]()
|
|
||||||
|
|
||||||
userConfigurator(mockConf)
|
|
||||||
|
|
||||||
var node = newEthereumNode(mockConf.keys,
|
|
||||||
mockConf.address,
|
|
||||||
mockConf.networkId,
|
|
||||||
mockConf.chain,
|
|
||||||
mockConf.clientId,
|
|
||||||
addAllCapabilities = false,
|
|
||||||
mockConf.compression())
|
|
||||||
|
|
||||||
mockConf.handshakes.sort do (lhs, rhs: ExpectedMsg) -> int:
|
|
||||||
# this is intentially sorted in reverse order, so we
|
|
||||||
# can add them in the correct order below.
|
|
||||||
return -cmp(lhs.msg.protocol.index, rhs.msg.protocol.index)
|
|
||||||
|
|
||||||
for h in mockConf.handshakes:
|
|
||||||
mockConf.expectedMsgs.addFirst h
|
|
||||||
|
|
||||||
for p in mockConf.protocols:
|
|
||||||
node.addCapability p
|
|
||||||
|
|
||||||
when false:
|
|
||||||
# TODO: This part doesn't work correctly yet.
|
|
||||||
# rlpx{Connect,Accept} control the handshake.
|
|
||||||
if mockConf.devp2pHandshake.response != nil:
|
|
||||||
mockConf.expectedMsgs.addFirst mockConf.devp2pHandshake
|
|
||||||
else:
|
|
||||||
proc sendHello(p: Peer, data: Rlp) {.async.} =
|
|
||||||
await p.hello(devp2pVersion,
|
|
||||||
mockConf.clientId,
|
|
||||||
node.capabilities,
|
|
||||||
uint(node.address.tcpPort),
|
|
||||||
node.keys.pubkey.getRaw())
|
|
||||||
|
|
||||||
mockConf.expectedMsgs.addFirst ExpectedMsg(
|
|
||||||
msg: makeProtoMsgPair(p2p.hello),
|
|
||||||
response: sendHello)
|
|
||||||
|
|
||||||
node.startListening()
|
|
||||||
return node
|
|
||||||
|
|
||||||
proc rlpxConnect*(node, otherNode: EthereumNode): Future[Peer] =
|
|
||||||
let otherAsRemote = newNode(otherNode.toENode())
|
|
||||||
return rlpx.rlpxConnect(node, otherAsRemote)
|
|
|
@ -1,141 +0,0 @@
|
||||||
#
|
|
||||||
# Ethereum P2P
|
|
||||||
# (c) Copyright 2018
|
|
||||||
# Status Research & Development GmbH
|
|
||||||
#
|
|
||||||
# Licensed under either of
|
|
||||||
# Apache License, version 2.0, (LICENSE-APACHEv2)
|
|
||||||
# MIT license (LICENSE-MIT)
|
|
||||||
|
|
||||||
import
|
|
||||||
std/[sequtils, strformat, options],
|
|
||||||
testutils/unittests, chronicles, chronos,
|
|
||||||
../../eth/[rlp, keys, p2p], ../../eth/p2p/mock_peers
|
|
||||||
|
|
||||||
const
|
|
||||||
clientId = "nim-eth-p2p/0.0.1"
|
|
||||||
|
|
||||||
type
|
|
||||||
AbcPeer = ref object
|
|
||||||
peerName: string
|
|
||||||
lastResponse: string
|
|
||||||
|
|
||||||
XyzPeer = ref object
|
|
||||||
messages: int
|
|
||||||
|
|
||||||
AbcNetwork = ref object
|
|
||||||
peers: seq[string]
|
|
||||||
|
|
||||||
p2pProtocol abc(version = 1,
|
|
||||||
peerState = AbcPeer,
|
|
||||||
networkState = AbcNetwork,
|
|
||||||
timeout = 100):
|
|
||||||
|
|
||||||
onPeerConnected do (peer: Peer):
|
|
||||||
await peer.hi "Bob"
|
|
||||||
let response = await peer.nextMsg(abc.hi)
|
|
||||||
peer.networkState.peers.add response.name
|
|
||||||
|
|
||||||
onPeerDisconnected do (peer: Peer, reason: DisconnectionReason):
|
|
||||||
echo "peer disconnected", peer
|
|
||||||
|
|
||||||
requestResponse:
|
|
||||||
proc abcReq(p: Peer, n: int) =
|
|
||||||
echo "got req ", n
|
|
||||||
await response.send(&"response to #{n}")
|
|
||||||
|
|
||||||
proc abcRes(p: Peer, data: string) =
|
|
||||||
echo "got response ", data
|
|
||||||
|
|
||||||
proc hi(p: Peer, name: string) =
|
|
||||||
echo "got hi from ", name
|
|
||||||
p.state.peerName = name
|
|
||||||
let query = 123
|
|
||||||
echo "sending req #", query
|
|
||||||
var r = await p.abcReq(query)
|
|
||||||
if r.isSome:
|
|
||||||
p.state.lastResponse = r.get.data
|
|
||||||
else:
|
|
||||||
p.state.lastResponse = "timeout"
|
|
||||||
|
|
||||||
p2pProtocol xyz(version = 1,
|
|
||||||
peerState = XyzPeer,
|
|
||||||
useRequestIds = false,
|
|
||||||
timeout = 100):
|
|
||||||
|
|
||||||
proc foo(p: Peer, s: string, a, z: int) =
|
|
||||||
p.state.messages += 1
|
|
||||||
if p.supports(abc):
|
|
||||||
echo p.state(abc).peerName
|
|
||||||
|
|
||||||
proc bar(p: Peer, i: int, s: string)
|
|
||||||
|
|
||||||
requestResponse:
|
|
||||||
proc xyzReq(p: Peer, n: int, timeout = 3.seconds) =
|
|
||||||
echo "got req ", n
|
|
||||||
|
|
||||||
proc xyzRes(p: Peer, data: string) =
|
|
||||||
echo "got response ", data
|
|
||||||
|
|
||||||
proc defaultTestingHandshake(_: type abc): abc.hi =
|
|
||||||
result.name = "John Doe"
|
|
||||||
|
|
||||||
proc localAddress(port: int): Address =
|
|
||||||
let port = Port(port)
|
|
||||||
result = Address(udpPort: port, tcpPort: port, ip: parseIpAddress("127.0.0.1"))
|
|
||||||
|
|
||||||
template asyncTest(name, body: untyped) =
|
|
||||||
test name:
|
|
||||||
proc scenario {.async.} = body
|
|
||||||
waitFor scenario()
|
|
||||||
|
|
||||||
template sendResponseWithId(peer: Peer, proto, msg: untyped, reqId: int, data: varargs[untyped]): auto =
|
|
||||||
msg(ResponseWithId[proto.msg](peer: peer, id: reqId), data)
|
|
||||||
|
|
||||||
template sendResponse(peer: Peer, proto, msg: untyped, data: varargs[untyped]): auto =
|
|
||||||
msg(Response[proto.msg](peer), data)
|
|
||||||
|
|
||||||
asyncTest "network with 3 peers using custom protocols":
|
|
||||||
const useCompression = defined(useSnappy)
|
|
||||||
let localKeys = KeyPair.random()[]
|
|
||||||
let localAddress = localAddress(30303)
|
|
||||||
var localNode = newEthereumNode(localKeys, localAddress, 1, nil, useCompression = useCompression)
|
|
||||||
localNode.startListening()
|
|
||||||
|
|
||||||
var mock1 = newMockPeer do (m: MockConf):
|
|
||||||
m.addHandshake abc.hi(name: "Alice")
|
|
||||||
|
|
||||||
m.expect(abc.abcReq) do (peer: Peer, data: Rlp):
|
|
||||||
let reqId = data.readReqId()
|
|
||||||
await sendResponseWithId(peer, abc, abcRes, reqId, "mock response")
|
|
||||||
await sleepAsync(100)
|
|
||||||
let r = await peer.abcReq(1)
|
|
||||||
doAssert r.get.data == "response to #1"
|
|
||||||
|
|
||||||
m.expect(abc.abcRes)
|
|
||||||
|
|
||||||
var mock2 = newMockPeer do (m: MockConf):
|
|
||||||
m.addCapability xyz
|
|
||||||
m.addCapability abc
|
|
||||||
|
|
||||||
m.expect(abc.abcReq) # we'll let this one time out
|
|
||||||
|
|
||||||
m.expect(xyz.xyzReq) do (peer: Peer):
|
|
||||||
echo "got xyz req"
|
|
||||||
await sendResponse(peer, xyz, xyzRes, "mock peer data")
|
|
||||||
|
|
||||||
when useCompression:
|
|
||||||
m.useCompression = useCompression
|
|
||||||
|
|
||||||
discard await mock1.rlpxConnect(localNode)
|
|
||||||
let mock2Connection = await localNode.rlpxConnect(mock2)
|
|
||||||
|
|
||||||
let r = await mock2Connection.xyzReq(10)
|
|
||||||
check r.get.data == "mock peer data"
|
|
||||||
|
|
||||||
let abcNetState = localNode.protocolState(abc)
|
|
||||||
|
|
||||||
check:
|
|
||||||
abcNetState.peers.len == 2
|
|
||||||
"Alice" in abcNetState.peers
|
|
||||||
"John Doe" in abcNetState.peers
|
|
Loading…
Reference in New Issue