mirror of https://github.com/status-im/nim-eth.git
`enterList` now returns a bool
This commit is contained in:
parent
5b140af1cd
commit
e89e59aa59
|
@ -158,31 +158,42 @@ proc decryptGCM(key: array[16, byte], nonce, ct, authData: openarray[byte]): seq
|
||||||
result = @[]
|
result = @[]
|
||||||
dctx.clear()
|
dctx.clear()
|
||||||
|
|
||||||
proc decodePacketBody(typ: byte, body: openarray[byte], res: var Packet): bool =
|
type
|
||||||
if typ >= PacketKind.low.byte and typ <= PacketKind.high.byte:
|
DecodePacketResult = enum
|
||||||
|
decodingSuccessful
|
||||||
|
invalidPacketPayload
|
||||||
|
invalidPacketType
|
||||||
|
unsupportedPacketType
|
||||||
|
|
||||||
|
proc decodePacketBody(typ: byte,
|
||||||
|
body: openarray[byte],
|
||||||
|
res: var Packet): DecodePacketResult =
|
||||||
|
if typ < PacketKind.low.byte or typ > PacketKind.high.byte:
|
||||||
|
return invalidPacketType
|
||||||
|
|
||||||
let kind = cast[PacketKind](typ)
|
let kind = cast[PacketKind](typ)
|
||||||
res = Packet(kind: kind)
|
res = Packet(kind: kind)
|
||||||
var rlp = rlpFromBytes(@body.toRange)
|
var rlp = rlpFromBytes(@body.toRange)
|
||||||
rlp.enterList()
|
if rlp.enterList:
|
||||||
res.reqId = rlp.read(RequestId)
|
res.reqId = rlp.read(RequestId)
|
||||||
|
|
||||||
proc decode[T](rlp: var Rlp, v: var T) {.inline, nimcall.} =
|
proc decode[T](rlp: var Rlp, v: var T) {.inline, nimcall.} =
|
||||||
for k, v in v.fieldPairs:
|
for k, v in v.fieldPairs:
|
||||||
v = rlp.read(typeof(v))
|
v = rlp.read(typeof(v))
|
||||||
|
|
||||||
template decode(k: untyped) =
|
case kind
|
||||||
if k == kind:
|
of unused: return invalidPacketPayload
|
||||||
decode(rlp, res.k)
|
of ping: rlp.decode(res.ping)
|
||||||
result = true
|
of pong: rlp.decode(res.pong)
|
||||||
|
of findNode: rlp.decode(res.findNode)
|
||||||
|
of nodes: rlp.decode(res.nodes)
|
||||||
|
of regtopic, ticket, regconfirmation, topicquery:
|
||||||
|
# TODO Implement these packet types
|
||||||
|
return unsupportedPacketType
|
||||||
|
|
||||||
decode(ping)
|
return decodingSuccessful
|
||||||
decode(pong)
|
|
||||||
decode(findNode)
|
|
||||||
decode(nodes)
|
|
||||||
else:
|
else:
|
||||||
debug "unknown packet type ", typ
|
return invalidPacketPayload
|
||||||
|
|
||||||
return true
|
|
||||||
|
|
||||||
proc decodeAuthResp(c: Codec, fromId: NodeId, head: AuthHeader,
|
proc decodeAuthResp(c: Codec, fromId: NodeId, head: AuthHeader,
|
||||||
challenge: Whoareyou, secrets: var HandshakeSecrets, newNode: var Node): bool =
|
challenge: Whoareyou, secrets: var HandshakeSecrets, newNode: var Node): bool =
|
||||||
|
@ -215,6 +226,8 @@ proc decodeEncrypted*(c: var Codec,
|
||||||
var r = rlpFromBytes(input[32 .. ^1])
|
var r = rlpFromBytes(input[32 .. ^1])
|
||||||
var auth: AuthHeader
|
var auth: AuthHeader
|
||||||
var readKey: array[16, byte]
|
var readKey: array[16, byte]
|
||||||
|
logScope: sender = $fromAddr
|
||||||
|
|
||||||
if r.isList:
|
if r.isList:
|
||||||
# Handshake - rlp list indicates auth-header
|
# Handshake - rlp list indicates auth-header
|
||||||
|
|
||||||
|
@ -258,7 +271,12 @@ proc decodeEncrypted*(c: var Codec,
|
||||||
|
|
||||||
let body = decryptGCM(readKey, auth.auth, bodyEnc.toOpenArray, input[0 .. 31].toOpenArray)
|
let body = decryptGCM(readKey, auth.auth, bodyEnc.toOpenArray, input[0 .. 31].toOpenArray)
|
||||||
if body.len > 1:
|
if body.len > 1:
|
||||||
result = decodePacketBody(body[0], body.toOpenArray(1, body.high), packet)
|
let status = decodePacketBody(body[0], body.toOpenArray(1, body.high), packet)
|
||||||
|
if status == decodingSuccessful:
|
||||||
|
return true
|
||||||
|
else:
|
||||||
|
debug "Failed to decode discovery packet", reason = status
|
||||||
|
return false
|
||||||
|
|
||||||
proc newRequestId*(): RequestId =
|
proc newRequestId*(): RequestId =
|
||||||
if randomBytes(addr result, sizeof(result)) != sizeof(result):
|
if randomBytes(addr result, sizeof(result)) != sizeof(result):
|
||||||
|
|
|
@ -195,7 +195,8 @@ proc verifySignatureV4(r: Record, sigData: openarray[byte], content: seq[byte]):
|
||||||
proc verifySignature(r: Record): bool =
|
proc verifySignature(r: Record): bool =
|
||||||
var rlp = rlpFromBytes(r.raw.toRange)
|
var rlp = rlpFromBytes(r.raw.toRange)
|
||||||
let sz = rlp.listLen
|
let sz = rlp.listLen
|
||||||
rlp.enterList()
|
if not rlp.enterList:
|
||||||
|
return false
|
||||||
let sigData = rlp.read(Bytes)
|
let sigData = rlp.read(Bytes)
|
||||||
let content = block:
|
let content = block:
|
||||||
var writer = initRlpList(sz - 1)
|
var writer = initRlpList(sz - 1)
|
||||||
|
@ -219,12 +220,16 @@ proc fromBytesAux(r: var Record): bool =
|
||||||
return false
|
return false
|
||||||
|
|
||||||
var rlp = rlpFromBytes(r.raw.toRange)
|
var rlp = rlpFromBytes(r.raw.toRange)
|
||||||
|
if not rlp.isList:
|
||||||
|
return false
|
||||||
|
|
||||||
let sz = rlp.listLen
|
let sz = rlp.listLen
|
||||||
if sz < minRlpListLen or sz mod 2 != 0:
|
if sz < minRlpListLen or sz mod 2 != 0:
|
||||||
# Wrong rlp object
|
# Wrong rlp object
|
||||||
return false
|
return false
|
||||||
|
|
||||||
rlp.enterList()
|
# We already know we are working with a list
|
||||||
|
discard rlp.enterList()
|
||||||
rlp.skipElem() # Skip signature
|
rlp.skipElem() # Skip signature
|
||||||
|
|
||||||
r.seqNum = rlp.read(uint64)
|
r.seqNum = rlp.read(uint64)
|
||||||
|
|
|
@ -567,7 +567,7 @@ proc p2pProtocolBackendImpl*(protocol: P2PProtocol): Backend =
|
||||||
read = bindSym("read", brForceOpen)
|
read = bindSym("read", brForceOpen)
|
||||||
checkedRlpRead = bindSym "checkedRlpRead"
|
checkedRlpRead = bindSym "checkedRlpRead"
|
||||||
startList = bindSym "startList"
|
startList = bindSym "startList"
|
||||||
enterList = bindSym "enterList"
|
tryEnterList = bindSym "tryEnterList"
|
||||||
finish = bindSym "finish"
|
finish = bindSym "finish"
|
||||||
|
|
||||||
messagePrinter = bindSym "messagePrinter"
|
messagePrinter = bindSym "messagePrinter"
|
||||||
|
@ -677,7 +677,7 @@ proc p2pProtocolBackendImpl*(protocol: P2PProtocol): Backend =
|
||||||
|
|
||||||
let
|
let
|
||||||
paramCount = paramsToWrite.len
|
paramCount = paramsToWrite.len
|
||||||
readParamsPrelude = if paramCount > 1: newCall(enterList, receivedRlp)
|
readParamsPrelude = if paramCount > 1: newCall(tryEnterList, receivedRlp)
|
||||||
else: newStmtList()
|
else: newStmtList()
|
||||||
|
|
||||||
when tracingEnabled:
|
when tracingEnabled:
|
||||||
|
|
|
@ -104,16 +104,18 @@ proc loadMessageStats*(network: LesNetwork,
|
||||||
|
|
||||||
try:
|
try:
|
||||||
var statsRlp = rlpFromBytes(stats.toRange)
|
var statsRlp = rlpFromBytes(stats.toRange)
|
||||||
statsRlp.enterList
|
if not statsRlp.enterList:
|
||||||
|
notice "Found a corrupted LES stats record"
|
||||||
|
break readFromDB
|
||||||
|
|
||||||
let version = statsRlp.read(int)
|
let version = statsRlp.read(int)
|
||||||
if version != lesStatsVer:
|
if version != lesStatsVer:
|
||||||
notice "Found outdated LES stats record"
|
notice "Found an outdated LES stats record"
|
||||||
break readFromDB
|
break readFromDB
|
||||||
|
|
||||||
statsRlp >> network.messageStats
|
statsRlp >> network.messageStats
|
||||||
if network.messageStats.len <= les.messages[^1].id:
|
if network.messageStats.len <= les.messages[^1].id:
|
||||||
notice "Found incomplete LES stats record"
|
notice "Found an incomplete LES stats record"
|
||||||
break readFromDB
|
break readFromDB
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -147,10 +147,18 @@ proc append*(rlpWriter: var RlpWriter, value: StatusOptions) =
|
||||||
rlpWriter.append(rlpFromBytes(bytes.toRange))
|
rlpWriter.append(rlpFromBytes(bytes.toRange))
|
||||||
|
|
||||||
proc read*(rlp: var Rlp, T: typedesc[StatusOptions]): T =
|
proc read*(rlp: var Rlp, T: typedesc[StatusOptions]): T =
|
||||||
|
if not rlp.isList():
|
||||||
|
raise newException(RlpTypeMismatch,
|
||||||
|
"List expected, but the source RLP is not a list.")
|
||||||
|
|
||||||
let sz = rlp.listLen()
|
let sz = rlp.listLen()
|
||||||
rlp.enterList()
|
# We already know that we are working with a list
|
||||||
|
discard rlp.enterList()
|
||||||
for i in 0 ..< sz:
|
for i in 0 ..< sz:
|
||||||
rlp.enterList()
|
if not rlp.enterList():
|
||||||
|
raise newException(RlpTypeMismatch,
|
||||||
|
"List expected, but the source RLP is not a list.")
|
||||||
|
|
||||||
var k: KeyKind
|
var k: KeyKind
|
||||||
try:
|
try:
|
||||||
k = rlp.read(KeyKind)
|
k = rlp.read(KeyKind)
|
||||||
|
|
10
eth/rlp.nim
10
eth/rlp.nim
|
@ -242,10 +242,16 @@ proc currentElemEnd*(self: Rlp): int =
|
||||||
elif isBlob() or isList():
|
elif isBlob() or isList():
|
||||||
result += payloadOffset() + payloadBytesCount()
|
result += payloadOffset() + payloadBytesCount()
|
||||||
|
|
||||||
proc enterList*(self: var Rlp) =
|
proc enterList*(self: var Rlp): bool =
|
||||||
if not isList():
|
if not isList():
|
||||||
raise newException(RlpTypeMismatch, "List expected, but source RLP is not a list")
|
return false
|
||||||
|
|
||||||
position += payloadOffset()
|
position += payloadOffset()
|
||||||
|
return true
|
||||||
|
|
||||||
|
proc tryEnterList*(self: var Rlp) =
|
||||||
|
if not enterList():
|
||||||
|
raise newException(RlpTypeMismatch, "List expected, but source RLP is not a list")
|
||||||
|
|
||||||
proc skipElem*(rlp: var Rlp) =
|
proc skipElem*(rlp: var Rlp) =
|
||||||
rlp.position = rlp.currentElemEnd
|
rlp.position = rlp.currentElemEnd
|
||||||
|
|
|
@ -386,7 +386,8 @@ proc replaceValue(data: Rlp, key: NibblesRange, value: BytesRange): Bytes =
|
||||||
|
|
||||||
# XXX: This can be optimized to a direct bitwise copy of the source RLP
|
# XXX: This can be optimized to a direct bitwise copy of the source RLP
|
||||||
var iter = data
|
var iter = data
|
||||||
iter.enterList()
|
# We already know that we are working with a list
|
||||||
|
discard iter.enterList()
|
||||||
for i in 0 ..< 16:
|
for i in 0 ..< 16:
|
||||||
r.append iter
|
r.append iter
|
||||||
iter.skipElem
|
iter.skipElem
|
||||||
|
@ -511,7 +512,8 @@ proc deleteAt(self: var HexaryTrie;
|
||||||
else:
|
else:
|
||||||
var rlpRes = initRlpList(17)
|
var rlpRes = initRlpList(17)
|
||||||
var iter = origRlp
|
var iter = origRlp
|
||||||
iter.enterList
|
# We already know that we are working with a list
|
||||||
|
discard iter.enterList
|
||||||
for i in 0 ..< 16:
|
for i in 0 ..< 16:
|
||||||
rlpRes.append iter
|
rlpRes.append iter
|
||||||
iter.skipElem
|
iter.skipElem
|
||||||
|
|
|
@ -102,7 +102,7 @@ test "encode and decode lists":
|
||||||
var list = rlpFromBytes encodeList(rlp.listELem(1), rlp.listELem(0)).toRange
|
var list = rlpFromBytes encodeList(rlp.listELem(1), rlp.listELem(0)).toRange
|
||||||
|
|
||||||
# test that iteration with enterList/skipElem works as expected
|
# test that iteration with enterList/skipElem works as expected
|
||||||
list.enterList
|
discard list.enterList # We alreay know that we are working with a list
|
||||||
check list.toString == "Lorem ipsum dolor sit amet"
|
check list.toString == "Lorem ipsum dolor sit amet"
|
||||||
list.skipElem
|
list.skipElem
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue