mirror of
https://github.com/status-im/nim-eth-p2p.git
synced 2025-01-18 02:41:09 +00:00
eca93509b4
Enable by compiling with -d:p2pdump. A chronicles log file named p2p_messages.json will be created in the working directory. This file will be consumed by the upcoming Chronicles Tail GUI (more details will be provided on the wiki of this repo). Other changes: * Removes the use of package_visible_types (only partially so far) * Simplifies the new Snappy code a little bit
114 lines
3.3 KiB
Nim
114 lines
3.3 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)
|
|
#
|
|
|
|
## This module implements the Ethereum Wire Protocol:
|
|
## https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol
|
|
|
|
import
|
|
asyncdispatch2, stint, chronicles, rlp, eth_common/eth_types,
|
|
../rlpx, ../private/types, ../blockchain_utils, ../../eth_p2p
|
|
|
|
type
|
|
NewBlockHashesAnnounce* = object
|
|
hash: KeccakHash
|
|
number: uint
|
|
|
|
NewBlockAnnounce* = object
|
|
header*: BlockHeader
|
|
body* {.rlpInline.}: BlockBody
|
|
|
|
PeerState = ref object
|
|
initialized*: bool
|
|
bestBlockHash*: KeccakHash
|
|
bestDifficulty*: DifficultyInt
|
|
|
|
const
|
|
maxStateFetch* = 384
|
|
maxBodiesFetch* = 128
|
|
maxReceiptsFetch* = 256
|
|
maxHeadersFetch* = 192
|
|
protocolVersion* = 63
|
|
|
|
rlpxProtocol eth(version = protocolVersion,
|
|
peerState = PeerState,
|
|
useRequestIds = false):
|
|
|
|
onPeerConnected do (peer: Peer):
|
|
let
|
|
network = peer.network
|
|
chain = network.chain
|
|
bestBlock = chain.getBestBlockHeader
|
|
|
|
await peer.status(protocolVersion,
|
|
network.networkId,
|
|
bestBlock.difficulty,
|
|
bestBlock.blockHash,
|
|
chain.genesisHash)
|
|
|
|
let m = await peer.nextMsg(eth.status)
|
|
if m.networkId == network.networkId and m.genesisHash == chain.genesisHash:
|
|
debug "suitable peer", peer
|
|
else:
|
|
raise newException(UselessPeerError, "Eth handshake params mismatch")
|
|
peer.state.initialized = true
|
|
peer.state.bestDifficulty = m.totalDifficulty
|
|
peer.state.bestBlockHash = m.bestHash
|
|
|
|
proc status(peer: Peer,
|
|
protocolVersion: uint,
|
|
networkId: uint,
|
|
totalDifficulty: DifficultyInt,
|
|
bestHash: KeccakHash,
|
|
genesisHash: KeccakHash)
|
|
|
|
proc newBlockHashes(peer: Peer, hashes: openarray[NewBlockHashesAnnounce]) =
|
|
discard
|
|
|
|
proc transactions(peer: Peer, transactions: openarray[Transaction]) =
|
|
discard
|
|
|
|
requestResponse:
|
|
proc getBlockHeaders(peer: Peer, request: BlocksRequest) =
|
|
if request.maxResults > uint64(maxHeadersFetch):
|
|
await peer.disconnect(BreachOfProtocol)
|
|
return
|
|
|
|
await peer.blockHeaders(peer.network.chain.getBlockHeaders(request))
|
|
|
|
proc blockHeaders(p: Peer, headers: openarray[BlockHeader])
|
|
|
|
requestResponse:
|
|
proc getBlockBodies(peer: Peer, hashes: openarray[KeccakHash]) =
|
|
if hashes.len > maxBodiesFetch:
|
|
await peer.disconnect(BreachOfProtocol)
|
|
return
|
|
|
|
await peer.blockBodies(peer.network.chain.getBlockBodies(hashes))
|
|
|
|
proc blockBodies(peer: Peer, blocks: openarray[BlockBody])
|
|
|
|
proc newBlock(peer: Peer, bh: NewBlockAnnounce, totalDifficulty: DifficultyInt) =
|
|
discard
|
|
|
|
nextID 13
|
|
|
|
requestResponse:
|
|
proc getNodeData(peer: Peer, hashes: openarray[KeccakHash]) =
|
|
await peer.nodeData(peer.network.chain.getStorageNodes(hashes))
|
|
|
|
proc nodeData(peer: Peer, data: openarray[Blob])
|
|
|
|
requestResponse:
|
|
proc getReceipts(peer: Peer, hashes: openarray[KeccakHash]) =
|
|
await peer.receipts(peer.network.chain.getReceipts(hashes))
|
|
|
|
proc receipts(peer: Peer, receipts: openarray[Receipt])
|
|
|