Sync: Fix `NewBlockAnnounce` RLP decoding errors
Turns out `{.rlpInline.}` doesn't do anything. It's documented but not implemented. Due to this, whenever a peer sent us a `NewBlock` message, we had an RLP decoding error processing it, and disconnected the peer thinking it was the peer's error. These messages are sent often by good peers, so whenever we connected to a really good peer, we'd end up disconnecting from it due to this. Because a block body is a list of transactions, the parse errors looked suspiciously like EIP-2718/2976/2930/1559 typed transaction RLP errors. But it was a failure to parse `BlockBody` inline. Conveniently, the `EthBlock` type defined for another reason is encoded exactly the way `NewBlockAnnounce` needs to be, so we can reuse that type. This didn't stand out before updating to `eth/65`, because with old protocols we tend to only connect to old peers, which may be out of date themselves and have no new blocks to send. Also, we didn't really investigate occasional disconnects before, we assumed they're just part of P2P life. Signed-off-by: Jamie Lokier <jamie@shareable.org>
This commit is contained in:
parent
3161d395a6
commit
889a796b72
|
@ -21,9 +21,7 @@ type
|
||||||
hash: KeccakHash
|
hash: KeccakHash
|
||||||
number: uint64 # Note: Was `uint`, wrong on 32-bit targets.
|
number: uint64 # Note: Was `uint`, wrong on 32-bit targets.
|
||||||
|
|
||||||
NewBlockAnnounce* = object
|
NewBlockAnnounce* = EthBlock
|
||||||
header*: BlockHeader
|
|
||||||
body* {.rlpInline.}: BlockBody
|
|
||||||
|
|
||||||
ForkId* = object
|
ForkId* = object
|
||||||
forkHash: array[4, byte] # The RLP encoding must be exactly 4 bytes.
|
forkHash: array[4, byte] # The RLP encoding must be exactly 4 bytes.
|
||||||
|
@ -124,7 +122,9 @@ p2pProtocol eth(version = protocolVersion,
|
||||||
proc blockBodies(peer: Peer, blocks: openArray[BlockBody])
|
proc blockBodies(peer: Peer, blocks: openArray[BlockBody])
|
||||||
|
|
||||||
# User message 0x07: NewBlock.
|
# User message 0x07: NewBlock.
|
||||||
proc newBlock(peer: Peer, bh: NewBlockAnnounce, totalDifficulty: DifficultyInt) =
|
proc newBlock(peer: Peer, bh: EthBlock, totalDifficulty: DifficultyInt) =
|
||||||
|
# (Note, needs to use `EthBlock` instead of its alias `NewBlockAnnounce`
|
||||||
|
# because either `p2pProtocol` or RLPx doesn't work with an alias.)
|
||||||
discard
|
discard
|
||||||
|
|
||||||
# User message 0x08: NewPooledTransactionHashes.
|
# User message 0x08: NewPooledTransactionHashes.
|
||||||
|
|
Loading…
Reference in New Issue