diff --git a/eth/rlp/hash_writer.nim b/eth/rlp/hash_writer.nim index adaa2d0..0d49665 100644 --- a/eth/rlp/hash_writer.nim +++ b/eth/rlp/hash_writer.nim @@ -4,13 +4,13 @@ import nimcrypto/keccak, stew/[arraybuf, shims/macros], ./priv/defs, - utils + utils, + length_writer type RlpHashWriter* = object keccak: keccak.keccak256 - listLengths*: seq[int] - prefixLengths*: seq[int] + lengths*: seq[tuple[listLen, prefixLen: int]] listCount: int bigEndianBuf: array[8, byte] @@ -61,8 +61,8 @@ proc startList*(self: var RlpHashWriter, listSize: int) = self.writeCount(0, LIST_START_MARKER) else: let - prefixLen = self.prefixLengths[self.listCount] - listLen = self.listLengths[self.listCount] + prefixLen = self.lengths[self.listCount].prefixLen + listLen = self.lengths[self.listCount].listLen self.listCount += 1 @@ -74,13 +74,14 @@ proc startList*(self: var RlpHashWriter, listSize: int) = self.updateBigEndian(uint64(listLen), listLenBytes) +func initHashWriter*(tracker: var RlpLengthTracker): RlpHashWriter = + result.lengths = move(tracker.lengths) + template finish*(self: var RlpHashWriter): MDigest[self.keccak.bits] = - self.listLengths.setLen(0) - self.prefixLengths.setLen(0) + self.lengths.setLen(0) self.keccak.finish() func clear*(w: var RlpHashWriter) = # Prepare writer for reuse - w.listLengths.setLen(0) - w.prefixLengths.setLen(0) + w.lengths.setLen(0) diff --git a/eth/rlp/length_writer.nim b/eth/rlp/length_writer.nim index a10c512..70a387d 100644 --- a/eth/rlp/length_writer.nim +++ b/eth/rlp/length_writer.nim @@ -7,8 +7,7 @@ import type RlpLengthTracker* = object - prefixLengths*: seq[int] - listLengths*: seq[int] + lengths*: seq[tuple[listLen, prefixLen: int]] pendingLists: seq[tuple[idx, remainingItems, startLen: int]] listCount: int totalLength*: int @@ -29,8 +28,7 @@ proc maybeClosePendingLists(self: var RlpLengthTracker) = else: int(uint64(listLen).bytesNeeded) + 1 # save the list lengths and prefix lengths - self.listLengths[listIdx] = listLen - self.prefixLengths[listIdx] = prefixLen + self.lengths[listIdx] = (listLen, prefixLen) # close the list by deleting self.pendingLists.setLen(lastIdx) @@ -51,9 +49,8 @@ proc startList*(self: var RlpLengthTracker, listSize: int) = # open a list self.pendingLists.add((self.listCount, listSize, self.totalLength)) self.listCount += 1 - if self.listCount == self.listLengths.len: - self.listLengths.setLen(self.listLengths.len + LIST_LENGTH) - self.prefixLengths.setLen(self.prefixLengths.len + LIST_LENGTH) + if self.listCount == self.lengths.len: + self.lengths.setLen(self.lengths.len + LIST_LENGTH) func lengthCount(count: int): int {.inline.} = return if count < THRESHOLD_LIST_LEN: 1 @@ -76,10 +73,7 @@ func writeInt*(self: var RlpLengthTracker, i: SomeUnsignedInt) = func initLengthTracker*(): RlpLengthTracker = # we preset the lengths since we want to skip using add method for # these lists - result.prefixLengths = newSeqOfCap[int](LIST_LENGTH) - result.prefixLengths.setLen(LIST_LENGTH) - result.listLengths = newSeqOfCap[int](LIST_LENGTH) - result.listLengths.setLen(LIST_LENGTH) + result.lengths = newSeq[(int, int)](LIST_LENGTH) template finish*(self: RlpLengthTracker): int = doAssert self.pendingLists.len == 0, @@ -89,5 +83,4 @@ template finish*(self: RlpLengthTracker): int = func clear*(w: var RlpLengthTracker) = # Prepare writer for reuse w.pendingLists.setLen(0) - w.prefixLengths.setLen(0) - w.listLengths.setLen(0) + w.lengths.setLen(0) diff --git a/eth/rlp/two_pass_writer.nim b/eth/rlp/two_pass_writer.nim index 523c050..a589fe9 100644 --- a/eth/rlp/two_pass_writer.nim +++ b/eth/rlp/two_pass_writer.nim @@ -3,14 +3,14 @@ import pkg/results, stew/[arraybuf, assign2, shims/macros], ./priv/defs, - utils + utils, + length_writer type RlpTwoPassWriter* = object pendingLists*: seq[tuple[remainingItems, startPos, prefixLen: int]] output*: seq[byte] - prefixLengths*: seq[int] - listLengths*: seq[int] + lengths*: seq[tuple[listLen, prefixLen: int]] fillLevel: int listCount: int @@ -61,8 +61,8 @@ proc startList*(self: var RlpTwoPassWriter, listSize: int) = self.writeCount(0, LIST_START_MARKER) else: let - prefixLen = self.prefixLengths[self.listCount] - listLen = self.listLengths[self.listCount] + prefixLen = self.lengths[self.listCount].prefixLen + listLen = self.lengths[self.listCount].listLen self.listCount += 1 @@ -76,22 +76,19 @@ proc startList*(self: var RlpTwoPassWriter, listSize: int) = self.output.writeBigEndian(uint64(listLen), self.fillLevel - 1, listLenBytes) -func initTwoPassWriter*(length: int): RlpTwoPassWriter = +func initTwoPassWriter*(tracker: var RlpLengthTracker): RlpTwoPassWriter = result.fillLevel = 0 result.listCount = 0 - result.output = newSeqOfCap[byte](length) - result.output.setLen(length) + result.output = newSeq[byte](tracker.totalLength) + result.lengths = move(tracker.lengths) template finish*(self: RlpTwoPassWriter): seq[byte] = doAssert self.pendingLists.len == 0, "Insufficient number of elements written to a started list" - self.prefixLengths.setLen(0) - self.listLengths.setLen(0) + self.lengths.setLen(0) self.output func clear*(w: var RlpTwoPassWriter) = # Prepare writer for reuse w.pendingLists.setLen(0) w.output.setLen(0) - w.prefixLengths.setLen(0) - w.listLengths.setLen(0) diff --git a/eth/rlp/writer.nim b/eth/rlp/writer.nim index 1a7b614..986cd5f 100644 --- a/eth/rlp/writer.nim +++ b/eth/rlp/writer.nim @@ -189,9 +189,7 @@ proc encode*[T](v: T): seq[byte] = tracker.append(v) - var writer = initTwoPassWriter(tracker.totalLength) - writer.prefixLengths = tracker.prefixLengths - writer.listLengths = tracker.listLengths + var writer = initTwoPassWriter(tracker) writer.append(v) move(writer.finish) @@ -200,12 +198,10 @@ proc encodeHash*[T](v: T): Hash32 = mixin append var tracker = initLengthTracker() - var writer: RlpHashWriter tracker.append(v) - writer.prefixLengths = tracker.prefixLengths - writer.listLengths = tracker.listLengths + var writer = initHashWriter(tracker) writer.append(v) writer.finish.to(Hash32)