mirror of
https://github.com/status-im/nim-eth.git
synced 2025-01-12 23:34:16 +00:00
5234e30f8b
For a long time this caused invalid RLP parsing of `NewBlock` messages in the `eth` protocol. The `rlpInline` pragma was accepted but had no effect. We could implemented it, but it doesn't seem worth doing, with tests etc, as there's only one user which has been fixed another way. With `NewBlock`, whenever a peer sent us `NewBlock`, we'd get an RLP decoding error, 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 within a minute due to this. This went unnoticed for years, as we stayed connected to old peers which have no new blocks, and we weren't looking at peer quality, disconnect reasons or real-time blockchain updates anyway. Signed-off-by: Jamie Lokier <jamie@shareable.org>
41 lines
1.0 KiB
Nim
41 lines
1.0 KiB
Nim
import std/macros
|
|
|
|
template rlpIgnore* {.pragma.}
|
|
## Specifies that a certain field should be ignored for the purposes
|
|
## of RLP serialization
|
|
|
|
template rlpCustomSerialization* {.pragma.}
|
|
## This pragma can be applied to a record field to enable the
|
|
## use of custom `read` and `append` overloads that also take
|
|
## a reference to the object holding the field.
|
|
|
|
template enumerateRlpFields*[T](x: T, op: untyped) =
|
|
for f in fields(x):
|
|
when not hasCustomPragma(f, rlpIgnore):
|
|
op(f)
|
|
|
|
proc rlpFieldsCount*(T: type): int =
|
|
mixin enumerateRlpFields
|
|
|
|
proc helper: int =
|
|
var dummy: T
|
|
template countFields(x) = inc result
|
|
enumerateRlpFields(dummy, countFields)
|
|
|
|
const res = helper()
|
|
return res
|
|
|
|
macro rlpFields*(T: typedesc, fields: varargs[untyped]): untyped =
|
|
var body = newStmtList()
|
|
let
|
|
ins = genSym(nskParam, "instance")
|
|
op = genSym(nskParam, "op")
|
|
|
|
for field in fields:
|
|
body.add quote do: `op`(`ins`.`field`)
|
|
|
|
result = quote do:
|
|
template enumerateRlpFields*(`ins`: `T`, `op`: untyped) {.inject.} =
|
|
`body`
|
|
|