From 8c7a64d6ad92e899f87652e89bc1177acacdbd05 Mon Sep 17 00:00:00 2001 From: chirag-parmar Date: Thu, 31 Oct 2024 20:48:21 +0530 Subject: [PATCH] replace some logic --- eth/common/base_rlp.nim | 4 +- eth/rlp/{options.nim => results.nim} | 8 ++-- eth/rlp/writer.nim | 72 +++++++++++++--------------- 3 files changed, 39 insertions(+), 45 deletions(-) rename eth/rlp/{options.nim => results.nim} (90%) diff --git a/eth/common/base_rlp.nim b/eth/common/base_rlp.nim index 339d425..4765cfa 100644 --- a/eth/common/base_rlp.nim +++ b/eth/common/base_rlp.nim @@ -9,9 +9,9 @@ import std/typetraits, ./base, ../rlp, - ../rlp/options as rlp_options + ../rlp/results as rlp_results -export base, rlp, rlp_options +export base, rlp, rlp_results template read*[T](rlp: var Rlp, val: var T) = diff --git a/eth/rlp/options.nim b/eth/rlp/results.nim similarity index 90% rename from eth/rlp/options.nim rename to eth/rlp/results.nim index 546c39e..f2d3a81 100644 --- a/eth/rlp/options.nim +++ b/eth/rlp/results.nim @@ -1,5 +1,9 @@ import ../rlp -import results +import writer +import pkg/results + +export + rlp, results proc append*[T](w: var RlpWriter, val: Opt[T]) = mixin append @@ -16,5 +20,3 @@ proc read*[T](rlp: var Rlp, val: var Opt[T]) {.raises: [RlpError].} = else: rlp.skipElem -export - rlp, results diff --git a/eth/rlp/writer.nim b/eth/rlp/writer.nim index 545a14d..46951a5 100644 --- a/eth/rlp/writer.nim +++ b/eth/rlp/writer.nim @@ -1,6 +1,6 @@ import std/options, - results, + pkg/results, stew/[arraybuf, assign2, bitops2, shims/macros], ./priv/defs @@ -8,7 +8,7 @@ export arraybuf type RlpWriter* = object - pendingLists: seq[tuple[remainingItems, outBytes: int]] + pendingLists: seq[tuple[remainingItems, startPos: int]] output: seq[byte] RlpIntBuf* = ArrayBuf[9, byte] @@ -60,17 +60,16 @@ proc initRlpWriter*: RlpWriter = # expected to be short-lived, it doesn't hurt to allocate this buffer result.output = newSeqOfCap[byte](2000) -proc decRet(n: var int, delta: int): int = - n -= delta - n - proc maybeClosePendingLists(self: var RlpWriter) = while self.pendingLists.len > 0: let lastListIdx = self.pendingLists.len - 1 - doAssert self.pendingLists[lastListIdx].remainingItems >= 1 - if decRet(self.pendingLists[lastListIdx].remainingItems, 1) == 0: + doAssert self.pendingLists[lastListIdx].remainingItems > 0 + + self.pendingLists[lastListIdx].remainingItems -= 1 + # if one last item is remaining in the list + if self.pendingLists[lastListIdx].remainingItems == 0: # A list have been just finished. It was started in `startList`. - let listStartPos = self.pendingLists[lastListIdx].outBytes + let listStartPos = self.pendingLists[lastListIdx].startPos self.pendingLists.setLen lastListIdx # How many bytes were written since the start? @@ -111,23 +110,14 @@ proc startList*(self: var RlpWriter, listSize: int) = else: self.pendingLists.add((listSize, self.output.len)) -proc appendBlob(self: var RlpWriter, data: openArray[byte], startMarker: byte) = +proc appendBlob(self: var RlpWriter, data: openArray[byte]) = if data.len == 1 and byte(data[0]) < BLOB_START_MARKER: self.output.add byte(data[0]) self.maybeClosePendingLists() else: - self.output.writeCount(data.len, startMarker) + self.output.writeCount(data.len, BLOB_START_MARKER) self.appendRawBytes(data) -proc appendImpl(self: var RlpWriter, data: string) = - appendBlob(self, data.toOpenArrayByte(0, data.high), BLOB_START_MARKER) - -proc appendBlob(self: var RlpWriter, data: openArray[byte]) = - appendBlob(self, data, BLOB_START_MARKER) - -proc appendBlob(self: var RlpWriter, data: openArray[char]) = - appendBlob(self, data.toOpenArrayByte(0, data.high), BLOB_START_MARKER) - proc appendInt(self: var RlpWriter, i: SomeUnsignedInt) = # this is created as a separate proc as an extra precaution against # any overloading resolution problems when matching the IntLike concept. @@ -135,26 +125,32 @@ proc appendInt(self: var RlpWriter, i: SomeUnsignedInt) = self.maybeClosePendingLists() + +template appendImpl(self: var RlpWriter, data: openArray[byte]) = + self.appendBlob(data) + +template appendImpl(self: var RlpWriter, data: openArray[char]) = + self.appendBlob(data.toOpenArrayByte(0, data.high)) + +template appendImpl(self: var RlpWriter, data: string) = + self.appendBlob(data.toOpenArrayByte(0, data.high)) + template appendImpl(self: var RlpWriter, i: SomeUnsignedInt) = - appendInt(self, i) + self.appendInt(i) template appendImpl(self: var RlpWriter, e: enum) = - appendImpl(self, int(e)) + # TODO: check for negative enums + self.appendInt(uint64(e)) template appendImpl(self: var RlpWriter, b: bool) = - appendImpl(self, int(b)) + self.appendInt(uint64(b)) -proc appendImpl[T](self: var RlpWriter, listOrBlob: openArray[T]) = +proc appendImpl[T](self: var RlpWriter, list: openArray[T]) = mixin append - # TODO: This append proc should be overloaded by `openArray[byte]` after - # nim bug #7416 is fixed. - when T is (byte or char): - self.appendBlob(listOrBlob) - else: - self.startList listOrBlob.len - for i in 0 ..< listOrBlob.len: - self.append listOrBlob[i] + self.startList list.len + for i in 0 ..< list.len: + self.append list[i] proc countOptionalFields(T: type): int {.compileTime.} = mixin enumerateRlpFields @@ -253,20 +249,16 @@ proc appendRecordType*(self: var RlpWriter, obj: object|tuple, wrapInList = wrap enumerateRlpFields(obj, op) -proc appendImpl(self: var RlpWriter, data: object) {.inline.} = +template appendImpl(self: var RlpWriter, data: object) = self.appendRecordType(data) -proc appendImpl(self: var RlpWriter, data: tuple) {.inline.} = +template appendImpl(self: var RlpWriter, data: tuple) = self.appendRecordType(data) # We define a single `append` template with a pretty low specificity # score in order to facilitate easier overloading with user types: template append*[T](w: var RlpWriter; data: T) = - when data is (enum|bool): - # TODO detect negative enum values at compile time? - appendImpl(w, uint64(data)) - else: - appendImpl(w, data) + appendImpl(w, data) template append*(w: var RlpWriter; data: SomeSignedInt) = {.error: "Signed integer encoding is not defined for rlp".} @@ -277,7 +269,7 @@ proc initRlpList*(listSize: int): RlpWriter = # TODO: This should return a lent value template finish*(self: RlpWriter): seq[byte] = - doAssert self.pendingLists.len == 0, "Insufficient number of elements written to a started list" + doAssert self.pendingLists.len == 0, "Insufficient number of elements written to a started list" & $(self.pendingLists.len) self.output func clear*(w: var RlpWriter) =