|
61 | 61 | startNumber*: uint64 |
62 | 62 | offsets*: seq[int64] # Absolute positions in file |
63 | 63 |
|
64 | | -template lenu64(x: untyped): untyped = |
65 | | - uint64(len(x)) |
66 | | - |
67 | | -## Following procs are more e2s specific and copied from e2store.nim |
68 | | -## TODO: Split up e2store.nim between e2s and era1 specific parts and reuse |
69 | | -## e2s code. |
70 | | - |
71 | | -proc toString(v: IoErrorCode): string = |
72 | | - try: ioErrorMsg(v) |
73 | | - except Exception as e: raiseAssert e.msg |
74 | | - |
75 | | -proc append(f: IoHandle, data: openArray[byte]): Result[void, string] = |
76 | | - if (? writeFile(f, data).mapErr(toString)) != data.len.uint: |
77 | | - return err("could not write data") |
78 | | - ok() |
79 | | - |
80 | | -proc appendHeader(f: IoHandle, typ: Type, dataLen: int): Result[int64, string] = |
81 | | - if dataLen.uint64 > uint32.high: |
82 | | - return err("entry does not fit 32-bit length") |
83 | | - |
84 | | - let start = ? getFilePos(f).mapErr(toString) |
85 | | - |
86 | | - ? append(f, typ) |
87 | | - ? append(f, toBytesLE(dataLen.uint32)) |
88 | | - ? append(f, [0'u8, 0'u8]) |
89 | | - |
90 | | - ok(start) |
91 | | - |
92 | | -proc checkBytesLeft(f: IoHandle, expected: int64): Result[void, string] = |
93 | | - let size = ? getFileSize(f).mapErr(toString) |
94 | | - if expected > size: |
95 | | - return err("Record extends past end of file") |
96 | | - |
97 | | - let pos = ? getFilePos(f).mapErr(toString) |
98 | | - if expected > size - pos: |
99 | | - return err("Record extends past end of file") |
100 | | - |
101 | | - ok() |
102 | | - |
103 | | -proc readFileExact(f: IoHandle, buf: var openArray[byte]): Result[void, string] = |
104 | | - if (? f.readFile(buf).mapErr(toString)) != buf.len().uint: |
105 | | - return err("missing data") |
106 | | - ok() |
107 | | - |
108 | | -proc readHeader(f: IoHandle): Result[Header, string] = |
109 | | - var buf: array[10, byte] |
110 | | - ? readFileExact(f, buf.toOpenArray(0, 7)) |
111 | | - |
112 | | - var |
113 | | - typ: Type |
114 | | - discard typ.copyFrom(buf) |
115 | | - |
116 | | - # Conversion safe because we had only 4 bytes of length data |
117 | | - let len = (uint32.fromBytesLE(buf.toOpenArray(2, 5))).int64 |
118 | | - |
119 | | - # No point reading these.. |
120 | | - if len > int.high(): return err("header length exceeds int.high") |
121 | | - |
122 | | - # Must have at least that much data, or header is invalid |
123 | | - ? f.checkBytesLeft(len) |
124 | | - |
125 | | - ok(Header(typ: typ, len: int(len))) |
126 | | - |
127 | | -## Following types & procs are era1 specific |
128 | | - |
129 | | -type |
130 | 64 | Era1* = distinct uint64 # Period of 8192 blocks (not an exact time unit) |
131 | 65 |
|
132 | 66 | Era1Group* = object |
|
135 | 69 | # As stated, not really a time unit but nevertheless, need the borrows |
136 | 70 | ethTimeUnit Era1 |
137 | 71 |
|
138 | | -# Note: appendIndex, appendRecord and readIndex for BlockIndex are only |
139 | | -# different from its consensus layer counter parts because of usage of slot vs |
140 | | -# blockNumber. In practise, they do the same thing. |
| 72 | +template lenu64(x: untyped): untyped = |
| 73 | + uint64(len(x)) |
| 74 | + |
| 75 | +# Note: appendIndex, appendRecord and readIndex for BlockIndex are very similar |
| 76 | +# to its consensus layer counter parts. The difference lies in the naming of |
| 77 | +# slots vs block numbers and there is different behavior for the first era |
| 78 | +# (first slot) and the last era (era1 ends at merge block). |
| 79 | + |
141 | 80 | proc appendIndex*( |
142 | 81 | f: IoHandle, startNumber: uint64, offsets: openArray[int64]): |
143 | 82 | Result[int64, string] = |
|
0 commit comments