nim-eth/tests/p2p/shh_basic_client.nim

155 lines
5.1 KiB
Nim

#
# 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, options, strutils, parseopt],
chronos,
../../eth/[keys, rlp, p2p], eth/p2p/rlpx_protocols/[whisper_protocol],
../../eth/p2p/[discovery, enode, peer_pool, bootnodes, whispernodes]
const
DefaultListeningPort = 30303
Usage = """Usage:
tssh_client [options]
Options:
-p --port Listening port
--post Post messages
--watch Install filters
--mainnet Connect to main network (default local private)
--local Only local loopback
--help Display this help and exit"""
DockerBootnode = "enode://f41f87f084ed7df4a9fd0833e395f49c89764462d3c4bc16d061a3ae5e3e34b79eb47d61c2f62db95ff32ae8e20965e25a3c9d9b8dbccaa8e8d77ac6fc8efc06@172.17.0.2:30301"
type
ShhConfig* = object
listeningPort*: int
post*: bool
watch*: bool
main*: bool
local*: bool
proc processArguments*(): ShhConfig =
var opt = initOptParser()
var length = 0
for kind, key, value in opt.getopt():
case kind
of cmdArgument:
echo key
of cmdLongOption, cmdShortOption:
inc(length)
case key.toLowerAscii()
of "help", "h": quit(Usage, QuitSuccess)
of "port", "p":
result.listeningPort = value.parseInt
of "post":
result.post = true
of "watch":
result.watch = true
of "mainnet":
result.main = true
of "local":
result.local = true
else: quit(Usage)
of cmdEnd:
quit(Usage)
let config = processArguments()
var port: Port
var address: Address
var netId: uint
# config
if config.listeningPort != 0:
port = Port(config.listeningPort)
else:
port = Port(DefaultListeningPort)
if config.local:
address = Address(udpPort: port, tcpPort: port, ip: parseIpAddress("127.0.0.1"))
else:
address = Address(udpPort: port, tcpPort: port, ip: parseIpAddress("0.0.0.0"))
if config.main:
netId = 1
else:
netId = 15
let keypair = KeyPair.random()[]
var node = newEthereumNode(keypair, address, netId, nil, addAllCapabilities = false)
node.addCapability Whisper
# lets prepare some prearranged keypairs
let encPrivateKey = PrivateKey.fromHex(
"5dc5381cae54ba3174dc0d46040fe11614d0cc94d41185922585198b4fcef9d3")[]
let encPublicKey = encPrivateKey.toPublicKey()[]
let signPrivateKey = PrivateKey.fromHex(
"365bda0757d22212b04fada4b9222f8c3da59b49398fa04cf612481cd893b0a3")[]
let signPublicKey = signPrivateKey.toPublicKey()[]
var symKey: SymKey
# To test with geth: all 0's key is invalid in geth console
symKey[31] = 1
let topic = [byte 0x12, 0, 0, 0]
if config.main:
var bootnodes: seq[ENode] = @[]
for nodeId in MainnetBootnodes:
bootnodes.add(ENode.fromString(nodeId).expect("static nodes"))
asyncCheck node.connectToNetwork(bootnodes, true, true)
# main network has mostly non SHH nodes, so we connect directly to SHH nodes
for nodeId in WhisperNodes:
var whisperNode = newNode(ENode.fromString(nodeId).expect("static nodes"))
asyncCheck node.peerPool.connectToNode(whisperNode)
else:
let bootENode = ENode.fromString(DockerBootnode).expect("static node")
waitFor node.connectToNetwork(@[bootENode], true, true)
if config.watch:
proc handler(msg: ReceivedMessage) =
echo msg.decoded.payload.repr
# filter encrypted asym
discard node.subscribeFilter(initFilter(privateKey = some(encPrivateKey),
topics = @[topic]),
handler)
# filter encrypted asym + signed
discard node.subscribeFilter(initFilter(some(signPublicKey),
privateKey = some(encPrivateKey),
topics = @[topic]),
handler)
# filter encrypted sym
discard node.subscribeFilter(initFilter(symKey = some(symKey),
topics = @[topic]),
handler)
# filter encrypted sym + signed
discard node.subscribeFilter(initFilter(some(signPublicKey),
symKey = some(symKey),
topics = @[topic]),
handler)
if config.post:
# encrypted asym
discard node.postMessage(some(encPublicKey), ttl = 5, topic = topic,
payload = repeat(byte 65, 10))
poll()
# # encrypted asym + signed
discard node.postMessage(some(encPublicKey), src = some(signPrivateKey),
ttl = 5, topic = topic, payload = repeat(byte 66, 10))
poll()
# # encrypted sym
discard node.postMessage(symKey = some(symKey), ttl = 5, topic = topic,
payload = repeat(byte 67, 10))
poll()
# # encrypted sym + signed
discard node.postMessage(symKey = some(symKey), src = some(signPrivateKey),
ttl = 5, topic = topic, payload = repeat(byte 68, 10))
while true:
poll()