drop rlpx support (#679)
This commit is contained in:
parent
7dc2434e0d
commit
270c25c8b8
|
@ -57,84 +57,7 @@ proc setupNat(conf: BeaconNodeConf): tuple[ip: IpAddress,
|
|||
if extPorts.isSome:
|
||||
(result.tcpPort, result.udpPort) = extPorts.get()
|
||||
|
||||
when networkBackend == rlpx:
|
||||
import
|
||||
os,
|
||||
eth/[rlp, p2p, keys], gossipsub_protocol,
|
||||
eth/p2p/peer_pool # for log on connected peers
|
||||
|
||||
export
|
||||
p2p, rlp, gossipsub_protocol
|
||||
|
||||
const
|
||||
netBackendName* = "rlpx"
|
||||
IrrelevantNetwork* = UselessPeer
|
||||
|
||||
type
|
||||
Eth2Node* = EthereumNode
|
||||
Eth2NodeIdentity* = KeyPair
|
||||
BootstrapAddr* = ENode
|
||||
|
||||
proc getPersistentNetIdentity*(conf: BeaconNodeConf): Eth2NodeIdentity =
|
||||
let privateKeyFile = conf.dataDir / "network.privkey"
|
||||
var privKey: PrivateKey
|
||||
if not fileExists(privateKeyFile):
|
||||
privKey = newPrivateKey()
|
||||
createDir conf.dataDir.string
|
||||
writeFile(privateKeyFile, $privKey)
|
||||
else:
|
||||
privKey = initPrivateKey(readFile(privateKeyFile).string)
|
||||
|
||||
KeyPair(seckey: privKey, pubkey: privKey.getPublicKey())
|
||||
|
||||
proc getPersistenBootstrapAddr*(conf: BeaconNodeConf,
|
||||
ip: IpAddress, port: Port): BootstrapAddr =
|
||||
let
|
||||
identity = getPersistentNetIdentity(conf)
|
||||
address = Address(ip: ip, tcpPort: port, udpPort: port)
|
||||
|
||||
initENode(identity.pubKey, address)
|
||||
|
||||
proc isSameNode*(bootstrapNode: BootstrapAddr, id: Eth2NodeIdentity): bool =
|
||||
bootstrapNode.pubKey == id.pubKey
|
||||
|
||||
proc shortForm*(id: Eth2NodeIdentity): string =
|
||||
($id.pubKey)[0..5]
|
||||
|
||||
proc writeValue*(writer: var JsonWriter, value: BootstrapAddr) {.inline.} =
|
||||
writer.writeValue $value
|
||||
|
||||
proc readValue*(reader: var JsonReader, value: var BootstrapAddr) {.inline.} =
|
||||
value = initENode reader.readValue(string)
|
||||
|
||||
proc createEth2Node*(conf: BeaconNodeConf,
|
||||
bootstrapNodes: seq[BootstrapAddr]): Future[EthereumNode] {.async.} =
|
||||
let
|
||||
keys = getPersistentNetIdentity(conf)
|
||||
(ip, tcpPort, udpPort) = setupNat(conf)
|
||||
address = Address(ip: ip,
|
||||
tcpPort: tcpPort,
|
||||
udpPort: udpPort)
|
||||
|
||||
# TODO there are more networking options to add here: local bind ip, ipv6
|
||||
# etc.
|
||||
return newEthereumNode(keys, address, 0,
|
||||
nil, clientId)
|
||||
|
||||
proc saveConnectionAddressFile*(node: Eth2Node, filename: string) =
|
||||
writeFile(filename, $node.listeningAddress)
|
||||
|
||||
proc initAddress*(T: type BootstrapAddr, str: string): T =
|
||||
initENode(str)
|
||||
|
||||
proc initAddress*(T: type BootstrapAddr, ip: IpAddress, tcpPort: Port): T =
|
||||
# TODO
|
||||
discard
|
||||
|
||||
func peersCount*(node: Eth2Node): int =
|
||||
node.peerPool.len
|
||||
|
||||
else:
|
||||
when networkBackend in [libp2p, libp2pDaemon]:
|
||||
import
|
||||
os, random,
|
||||
stew/io, eth/async_utils,
|
||||
|
@ -362,3 +285,5 @@ else:
|
|||
shuffle peers
|
||||
if peers.len > maxPeers: peers.setLen(maxPeers)
|
||||
for p in peers: yield p
|
||||
else:
|
||||
{.fatal: "Unsupported network backend".}
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
import
|
||||
tables, sets, macros, base64,
|
||||
chronos, nimcrypto/sysrand, chronicles, json_serialization,
|
||||
eth/[p2p, rlp, async_utils], eth/p2p/[rlpx, peer_pool],
|
||||
spec/[datatypes, crypto],
|
||||
tracing/stacktraces
|
||||
|
||||
type
|
||||
TopicMsgHandler = proc (msg: string)
|
||||
|
||||
GossipSubPeer* = ref object
|
||||
sentMessages: HashSet[string]
|
||||
subscribedFor: HashSet[string]
|
||||
|
||||
GossipSubNetwork* = ref object
|
||||
topicSubscribers: Table[string, TopicMsgHandler]
|
||||
handledMessages: HashSet[string]
|
||||
|
||||
proc initProtocolState*(network: GossipSubNetwork, _: EthereumNode) =
|
||||
network.topicSubscribers = initTable[string, TopicMsgHandler]()
|
||||
network.handledMessages = initSet[string]()
|
||||
|
||||
proc initProtocolState*(peer: GossipSubPeer, _: Peer) =
|
||||
peer.sentMessages = initSet[string]()
|
||||
peer.subscribedFor = initSet[string]()
|
||||
|
||||
proc trySubscribing(peer: Peer, topic: string) {.gcsafe.}
|
||||
proc tryEmitting(peer: Peer, topic: string,
|
||||
msgId: string, msg: string): Future[void] {.gcsafe.}
|
||||
|
||||
p2pProtocol GossipSub(version = 1,
|
||||
rlpxName = "gss",
|
||||
peerState = GossipSubPeer,
|
||||
networkState = GossipSubNetwork):
|
||||
# This is a very barebones emulation of the GossipSub protocol
|
||||
# available in LibP2P:
|
||||
|
||||
onPeerConnected do (peer: Peer):
|
||||
info "GossipSub Peer connected", peer
|
||||
let gossipNet = peer.networkState
|
||||
for topic, _ in gossipNet.topicSubscribers:
|
||||
peer.trySubscribing(topic)
|
||||
|
||||
onPeerDisconnected do (peer: Peer, reason: DisconnectionReason):
|
||||
info "GossipSub Peer disconnected", peer, reason
|
||||
|
||||
proc subscribeFor(peer: Peer, topic: string) =
|
||||
peer.state.subscribedFor.incl topic
|
||||
|
||||
proc emit(peer: Peer, topic: string, msgId: string, msg: string) =
|
||||
if msgId in peer.networkState.handledMessages:
|
||||
trace "Ignored previously handled message", msgId
|
||||
return
|
||||
|
||||
peer.networkState.handledMessages.incl msgId
|
||||
|
||||
for p in peer.network.peers(GossipSub):
|
||||
if msgId notin p.state.sentMessages and topic in p.state.subscribedFor:
|
||||
p.state.sentMessages.incl msgId
|
||||
traceAsyncErrors p.tryEmitting(topic, msgId, msg)
|
||||
|
||||
{.gcsafe.}:
|
||||
let handler = peer.networkState.topicSubscribers.getOrDefault(topic)
|
||||
if handler != nil:
|
||||
handler(msg)
|
||||
|
||||
proc trySubscribing(peer: Peer, topic: string) =
|
||||
var fut = peer.subscribeFor(topic)
|
||||
fut.addCallback do (arg: pointer):
|
||||
if fut.failed:
|
||||
debug "Failed to subscribe to topic with GossipSub peer", topic, peer
|
||||
|
||||
proc tryEmitting(peer: Peer, topic: string,
|
||||
msgId: string, msg: string): Future[void] =
|
||||
var fut = peer.emit(topic, msgId, msg)
|
||||
fut.addCallback do (arg: pointer):
|
||||
if fut.failed:
|
||||
debug "GossipSub message not delivered to Peer", peer
|
||||
return fut
|
||||
|
||||
proc subscribe*[MsgType](node: EthereumNode,
|
||||
topic: string,
|
||||
userHandler: proc(msg: MsgType)) {.async.}=
|
||||
var gossipNet = node.protocolState(GossipSub)
|
||||
gossipNet.topicSubscribers[topic] = proc (msg: string) =
|
||||
userHandler Json.decode(msg, MsgType)
|
||||
|
||||
for peer in node.peers(GossipSub):
|
||||
peer.trySubscribing(topic)
|
||||
|
||||
proc broadcast*(node: EthereumNode, topic: string, msg: auto) =
|
||||
var randBytes: array[10, byte];
|
||||
if randomBytes(randBytes) != 10:
|
||||
warn "Failed to generate random message id"
|
||||
|
||||
let msg = Json.encode(msg)
|
||||
let msgId = base64.encode(randBytes)
|
||||
trace "Sending GossipSub message", msgId
|
||||
|
||||
for peer in node.peers(GossipSub):
|
||||
if topic in peer.state(GossipSub).subscribedFor:
|
||||
traceAsyncErrors peer.tryEmitting(topic, msgId, msg)
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
import
|
||||
stew/[endians2, objects, byteutils], hashes, nimcrypto/utils,
|
||||
blscurve, json_serialization,
|
||||
../version, digest,
|
||||
digest,
|
||||
chronicles
|
||||
|
||||
export
|
||||
|
@ -250,31 +250,6 @@ else:
|
|||
proc newPrivKey*(): ValidatorPrivKey =
|
||||
SigKey.random()
|
||||
|
||||
when networkBackend == rlpx:
|
||||
import eth/rlp
|
||||
|
||||
when ValidatorPubKey is BlsValue:
|
||||
proc append*(writer: var RlpWriter, value: ValidatorPubKey) =
|
||||
writer.append if value.kind == Real: value.blsValue.getBytes()
|
||||
else: value.blob
|
||||
else:
|
||||
proc append*(writer: var RlpWriter, value: ValidatorPubKey) =
|
||||
writer.append value.getBytes()
|
||||
|
||||
proc read*(rlp: var Rlp, T: type ValidatorPubKey): T {.inline.} =
|
||||
result.initFromBytes rlp.toBytes.toOpenArray
|
||||
|
||||
when ValidatorSig is BlsValue:
|
||||
proc append*(writer: var RlpWriter, value: ValidatorSig) =
|
||||
writer.append if value.kind == Real: value.blsValue.getBytes()
|
||||
else: value.blob
|
||||
else:
|
||||
proc append*(writer: var RlpWriter, value: ValidatorSig) =
|
||||
writer.append value.getBytes()
|
||||
|
||||
proc read*(rlp: var Rlp, T: type ValidatorSig): T {.inline.} =
|
||||
result.initFromBytes rlp.toBytes.toOpenArray
|
||||
|
||||
proc writeValue*(writer: var JsonWriter, value: VerKey) {.inline.} =
|
||||
writer.writeValue($value)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import
|
||||
macros, hashes, json, strutils, tables,
|
||||
stew/[byteutils, bitseqs], chronicles,
|
||||
../version, ../ssz/types, ./crypto, ./digest
|
||||
../ssz/types, ./crypto, ./digest
|
||||
|
||||
# TODO Data types:
|
||||
# Presently, we're reusing the data types from the serialization (uint64) in the
|
||||
|
@ -365,16 +365,6 @@ type
|
|||
Table[Epoch, seq[ValidatorIndex]]
|
||||
committee_count_cache*: Table[Epoch, uint64]
|
||||
|
||||
when networkBackend == rlpx:
|
||||
import eth/rlp/bitseqs as rlpBitseqs
|
||||
export read, append
|
||||
|
||||
proc read*(rlp: var Rlp, T: type BitList): T {.inline.} =
|
||||
T rlp.read(BitSeq)
|
||||
|
||||
proc append*(writer: var RlpWriter, value: BitList) =
|
||||
writer.append BitSeq(value)
|
||||
|
||||
template foreachSpecType*(op: untyped) =
|
||||
## These are all spec types that will appear in network messages
|
||||
## and persistent consensus data. This helper template is useful
|
||||
|
@ -486,13 +476,6 @@ template ethTimeUnit(typ: type) {.dirty.} =
|
|||
proc `%`*(x: typ): JsonNode {.borrow.}
|
||||
|
||||
# Serialization
|
||||
when networkBackend == rlpx:
|
||||
proc read*(rlp: var Rlp, T: type typ): typ {.inline.} =
|
||||
typ(rlp.read(uint64))
|
||||
|
||||
proc append*(writer: var RlpWriter, value: typ) =
|
||||
writer.append uint64(value)
|
||||
|
||||
proc writeValue*(writer: var JsonWriter, value: typ) =
|
||||
writeValue(writer, uint64 value)
|
||||
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
import
|
||||
options, tables, sets, macros,
|
||||
chronicles, chronos, metrics, stew/ranges/bitranges,
|
||||
spec/[datatypes, crypto, digest, helpers], eth/rlp,
|
||||
spec/[datatypes, crypto, digest, helpers],
|
||||
beacon_node_types, eth2_network, block_pool, ssz
|
||||
|
||||
when networkBackend == rlpx:
|
||||
import eth/rlp/options as rlpOptions
|
||||
template libp2pProtocol*(name: string, version: int) {.pragma.}
|
||||
elif networkBackend == libp2p:
|
||||
when networkBackend == libp2p:
|
||||
import libp2p/switch
|
||||
|
||||
declarePublicGauge libp2p_peers, "Number of libp2p peers"
|
||||
|
|
|
@ -2,15 +2,13 @@ type
|
|||
NetworkBackendType* = enum
|
||||
libp2p
|
||||
libp2pDaemon
|
||||
rlpx
|
||||
|
||||
const
|
||||
NETWORK_TYPE {.strdefine.} = "libp2p_daemon"
|
||||
|
||||
networkBackend* = when NETWORK_TYPE == "rlpx": rlpx
|
||||
elif NETWORK_TYPE == "libp2p": libp2p
|
||||
networkBackend* = when NETWORK_TYPE == "libp2p": libp2p
|
||||
elif NETWORK_TYPE == "libp2p_daemon": libp2pDaemon
|
||||
else: {.fatal: "The 'NETWORK_TYPE' should be either 'libp2p', 'libp2p_daemon' or 'rlpx'" .}
|
||||
else: {.fatal: "The 'NETWORK_TYPE' should be either 'libp2p', 'libp2p_daemon'" .}
|
||||
|
||||
const
|
||||
copyrights* = "Copyright (c) 2019 Status Research & Development GmbH"
|
||||
|
|
|
@ -23,7 +23,6 @@ asyncTest "connect two nodes":
|
|||
|
||||
echo "Node 1 persistent address: ", n1PersistentAddress
|
||||
|
||||
when networkBackend != rlpx:
|
||||
var n1ActualAddress = await n1.daemon.identity()
|
||||
echo "Node 1 actual address:", n1ActualAddress
|
||||
|
||||
|
|
Loading…
Reference in New Issue