mirror of https://github.com/status-im/nim-eth.git
Fix stability issues (#512)
* Fix stability issues why: Handling malformed messages typically raises `RangeError` exceptions when de-serialising RLP, or decoding message data. This is an (incomplete) attempt to weed out some out it driven by real live tests. remark: Employing the new `snap` protocol there might be different views on what the messages really contain (currently specs are more a hint.) * Update RLP exception handling * Undo effect-less patch why: problem occurred somewhere above the try/catch handler * Using `checkedEnumAssign()` for RLP enum
This commit is contained in:
parent
dacf827a86
commit
8761ea3222
|
@ -3,6 +3,9 @@ import
|
||||||
stew/[endians2, byteutils], chronicles, stint, nimcrypto/[keccak, hash],
|
stew/[endians2, byteutils], chronicles, stint, nimcrypto/[keccak, hash],
|
||||||
../rlp, ../trie/[trie_defs, db]
|
../rlp, ../trie/[trie_defs, db]
|
||||||
|
|
||||||
|
from stew/objects
|
||||||
|
import checkedEnumAssign
|
||||||
|
|
||||||
export
|
export
|
||||||
stint, read, append, KeccakHash, rlp, options
|
stint, read, append, KeccakHash, rlp, options
|
||||||
|
|
||||||
|
@ -454,14 +457,21 @@ proc readTxTyped(rlp: var Rlp, tx: var Transaction) {.inline.} =
|
||||||
let txType = rlp.getByteValue
|
let txType = rlp.getByteValue
|
||||||
rlp.position += 1
|
rlp.position += 1
|
||||||
|
|
||||||
case TxType(txType):
|
var txVal: TxType
|
||||||
|
if checkedEnumAssign(txVal, txType):
|
||||||
|
case txVal:
|
||||||
of TxEip2930:
|
of TxEip2930:
|
||||||
rlp.readTxEip2930(tx)
|
rlp.readTxEip2930(tx)
|
||||||
|
return
|
||||||
of TxEip1559:
|
of TxEip1559:
|
||||||
rlp.readTxEip1559(tx)
|
rlp.readTxEip1559(tx)
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
raise newException(UnsupportedRlpError,
|
discard
|
||||||
"TypedTransaction type must be 1 or 2 in this version, got " & $txType)
|
|
||||||
|
raise newException(UnsupportedRlpError,
|
||||||
|
"TypedTransaction type must be 1 or 2 in this version, got " & $txType)
|
||||||
|
|
||||||
|
|
||||||
proc read*(rlp: var Rlp, T: type Transaction): T =
|
proc read*(rlp: var Rlp, T: type Transaction): T =
|
||||||
# Individual transactions are encoded and stored as either `RLP([fields..])`
|
# Individual transactions are encoded and stored as either `RLP([fields..])`
|
||||||
|
|
|
@ -62,22 +62,25 @@ proc read(rlp: var Rlp; T: type DisconnectionReasonList): T
|
||||||
# Be strict here: The expression `rlp.read(DisconnectionReasonList)`
|
# Be strict here: The expression `rlp.read(DisconnectionReasonList)`
|
||||||
# accepts lists with at least one item. The array expression wants
|
# accepts lists with at least one item. The array expression wants
|
||||||
# exactly one item.
|
# exactly one item.
|
||||||
return DisconnectionReasonList(
|
if rlp.rawData.len < 3:
|
||||||
value: rlp.read(array[1,DisconnectionReason])[0])
|
# avoids looping through all items when parsing for an overlarge array
|
||||||
|
return DisconnectionReasonList(
|
||||||
|
value: rlp.read(array[1,DisconnectionReason])[0])
|
||||||
|
|
||||||
# Also accepted: a single byte reason code. Is is typically used
|
# Also accepted: a single byte reason code. Is is typically used
|
||||||
# by variants of the reference implementation `Geth`
|
# by variants of the reference implementation `Geth`
|
||||||
if rlp.blobLen <= 1:
|
elif rlp.blobLen <= 1:
|
||||||
return DisconnectionReasonList(
|
return DisconnectionReasonList(
|
||||||
value: rlp.read(DisconnectionReason))
|
value: rlp.read(DisconnectionReason))
|
||||||
|
|
||||||
# Also accepted: a blob of a list (aka object) of reason code. It is
|
# Also accepted: a blob of a list (aka object) of reason code. It is
|
||||||
# used by `bor`, a `geth` fork
|
# used by `bor`, a `geth` fork
|
||||||
var subList = rlp.toBytes.rlpFromBytes
|
elif rlp.blobLen < 4:
|
||||||
if subList.isList:
|
var subList = rlp.toBytes.rlpFromBytes
|
||||||
# Ditto, see above.
|
if subList.isList:
|
||||||
return DisconnectionReasonList(
|
# Ditto, see above.
|
||||||
value: subList.read(array[1,DisconnectionReason])[0])
|
return DisconnectionReasonList(
|
||||||
|
value: subList.read(array[1,DisconnectionReason])[0])
|
||||||
|
|
||||||
raise newException(RlpTypeMismatch, "Single entry list expected")
|
raise newException(RlpTypeMismatch, "Single entry list expected")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue