2019-02-05 15:40:29 +00:00
|
|
|
#
|
|
|
|
# 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
|
2019-02-06 16:01:04 +00:00
|
|
|
sequtils, options, strutils, parseopt, chronos,
|
2019-02-05 15:40:29 +00:00
|
|
|
eth/[keys, rlp, p2p], eth/p2p/rlpx_protocols/[whisper_protocol],
|
2019-08-15 11:04:04 +00:00
|
|
|
eth/p2p/[discovery, enode, peer_pool, bootnodes, whispernodes]
|
2019-02-05 15:40:29 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2019-06-11 12:44:24 +00:00
|
|
|
let keypair = newKeyPair()
|
|
|
|
var node = newEthereumNode(keypair, address, netId, nil, addAllCapabilities = false)
|
2019-02-05 15:40:29 +00:00
|
|
|
node.addCapability Whisper
|
|
|
|
|
|
|
|
# lets prepare some prearranged keypairs
|
|
|
|
let encPrivateKey = initPrivateKey("5dc5381cae54ba3174dc0d46040fe11614d0cc94d41185922585198b4fcef9d3")
|
|
|
|
let encPublicKey = encPrivateKey.getPublicKey()
|
|
|
|
let signPrivateKey = initPrivateKey("365bda0757d22212b04fada4b9222f8c3da59b49398fa04cf612481cd893b0a3")
|
|
|
|
let signPublicKey = signPrivateKey.getPublicKey()
|
|
|
|
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] = @[]
|
2019-08-15 11:04:04 +00:00
|
|
|
for nodeId in MainnetBootnodes:
|
2019-02-05 15:40:29 +00:00
|
|
|
var bootnode: ENode
|
|
|
|
discard initENode(nodeId, bootnode)
|
|
|
|
bootnodes.add(bootnode)
|
|
|
|
|
|
|
|
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 whisperENode: ENode
|
|
|
|
discard initENode(nodeId, whisperENode)
|
|
|
|
var whisperNode = newNode(whisperENode)
|
|
|
|
asyncCheck node.peerPool.connectToNode(whisperNode)
|
|
|
|
else:
|
|
|
|
var bootENode: ENode
|
|
|
|
discard initENode(DockerBootNode, bootENode)
|
|
|
|
waitFor node.connectToNetwork(@[bootENode], true, true)
|
|
|
|
|
|
|
|
if config.watch:
|
|
|
|
proc handler(msg: ReceivedMessage) =
|
|
|
|
echo msg.decoded.payload.repr
|
|
|
|
|
|
|
|
# filter encrypted asym
|
|
|
|
discard node.subscribeFilter(newFilter(privateKey = some(encPrivateKey),
|
|
|
|
topics = @[topic]),
|
|
|
|
handler)
|
|
|
|
# filter encrypted asym + signed
|
|
|
|
discard node.subscribeFilter(newFilter(some(signPublicKey),
|
|
|
|
privateKey = some(encPrivateKey),
|
|
|
|
topics = @[topic]),
|
|
|
|
handler)
|
|
|
|
# filter encrypted sym
|
|
|
|
discard node.subscribeFilter(newFilter(symKey = some(symKey),
|
|
|
|
topics = @[topic]),
|
|
|
|
handler)
|
|
|
|
# filter encrypted sym + signed
|
|
|
|
discard node.subscribeFilter(newFilter(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()
|