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:
Jamie Lokier 2021-07-27 01:17:52 +01:00
parent 3161d395a6
commit 889a796b72
No known key found for this signature in database
GPG Key ID: CBC25C68435C30A2
1 changed files with 4 additions and 4 deletions

View File

@ -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.