Skip to content

Commit 85938dd

Browse files
authored
internal/era: update block index format to be based on record offset (#28959)
As mentioned in #26621, the block index format for era1 is not in line with the regular era block index. This change modifies the index so all relative offsets are based against the beginning of the block index record.
1 parent ac5aa67 commit 85938dd

File tree

3 files changed

+19
-22
lines changed

3 files changed

+19
-22
lines changed

cmd/utils/history_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func TestHistoryImportAndExport(t *testing.T) {
134134
for j := 0; it.Next(); j++ {
135135
n := i*int(step) + j
136136
if it.Error() != nil {
137-
t.Fatalf("error reading block entry %d: %v", n, err)
137+
t.Fatalf("error reading block entry %d: %v", n, it.Error())
138138
}
139139
block, receipts, err := it.BlockAndReceipts()
140140
if err != nil {

internal/era/builder.go

+10-14
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import (
4949
// CompressedBody = { type: [0x04, 0x00], data: snappyFramed(rlp(body)) }
5050
// CompressedReceipts = { type: [0x05, 0x00], data: snappyFramed(rlp(receipts)) }
5151
// TotalDifficulty = { type: [0x06, 0x00], data: uint256(header.total_difficulty) }
52-
// Accumulator = { type: [0x07, 0x00], data: accumulator-root }
52+
// AccumulatorRoot = { type: [0x07, 0x00], data: accumulator-root }
5353
// BlockIndex = { type: [0x32, 0x66], data: block-index }
5454
//
5555
// Accumulator is computed by constructing an SSZ list of header-records of length at most
@@ -64,8 +64,8 @@ import (
6464
// block-index := starting-number | index | index | index ... | count
6565
//
6666
// starting-number is the first block number in the archive. Every index is a
67-
// defined relative to index's location in the file. The total number of block
68-
// entries in the file is recorded in count.
67+
// defined relative to beginning of the record. The total number of block
68+
// entries in the file is recorded with count.
6969
//
7070
// Due to the accumulator size limit of 8192, the maximum number of blocks in
7171
// an Era1 batch is also 8192.
@@ -115,12 +115,14 @@ func (b *Builder) Add(block *types.Block, receipts types.Receipts, td *big.Int)
115115
func (b *Builder) AddRLP(header, body, receipts []byte, number uint64, hash common.Hash, td, difficulty *big.Int) error {
116116
// Write Era1 version entry before first block.
117117
if b.startNum == nil {
118-
if err := writeVersion(b.w); err != nil {
118+
n, err := b.w.Write(TypeVersion, nil)
119+
if err != nil {
119120
return err
120121
}
121-
n := number
122-
b.startNum = &n
122+
startNum := number
123+
b.startNum = &startNum
123124
b.startTd = new(big.Int).Sub(td, difficulty)
125+
b.written += n
124126
}
125127
if len(b.indexes) >= MaxEra1Size {
126128
return fmt.Errorf("exceeds maximum batch size of %d", MaxEra1Size)
@@ -169,7 +171,7 @@ func (b *Builder) Finalize() (common.Hash, error) {
169171
return common.Hash{}, fmt.Errorf("error writing accumulator: %w", err)
170172
}
171173
// Get beginning of index entry to calculate block relative offset.
172-
base := int64(b.written + (3 * 8)) // skip e2store header (type, length) and start block
174+
base := int64(b.written)
173175

174176
// Construct block index. Detailed format described in Builder
175177
// documentation, but it is essentially encoded as:
@@ -186,7 +188,7 @@ func (b *Builder) Finalize() (common.Hash, error) {
186188
// relative offset, the corresponding block can be quickly read by
187189
// performing a seek relative to the current position.
188190
for i, offset := range b.indexes {
189-
relative := int64(offset) - (base + int64(i)*8)
191+
relative := int64(offset) - base
190192
binary.LittleEndian.PutUint64(index[8+i*8:], uint64(relative))
191193
}
192194
binary.LittleEndian.PutUint64(index[8+count*8:], uint64(count))
@@ -220,9 +222,3 @@ func (b *Builder) snappyWrite(typ uint16, in []byte) error {
220222
}
221223
return nil
222224
}
223-
224-
// writeVersion writes a version entry to e2store.
225-
func writeVersion(w *e2store.Writer) error {
226-
_, err := w.Write(TypeVersion, nil)
227-
return err
228-
}

internal/era/era.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -221,20 +221,21 @@ func (e *Era) Count() uint64 {
221221
// is the absolute block number desired.
222222
func (e *Era) readOffset(n uint64) (int64, error) {
223223
var (
224-
firstIndex = -8 - int64(e.m.count)*8 // size of count - index entries
225-
indexOffset = int64(n-e.m.start) * 8 // desired index * size of indexes
226-
offOffset = e.m.length + firstIndex + indexOffset // offset of block offset
224+
blockIndexRecordOffset = e.m.length - 24 - int64(e.m.count)*8 // skips start, count, and header
225+
firstIndex = blockIndexRecordOffset + 16 // first index after header / start-num
226+
indexOffset = int64(n-e.m.start) * 8 // desired index * size of indexes
227+
offOffset = firstIndex + indexOffset // offset of block offset
227228
)
228229
e.mu.Lock()
229230
defer e.mu.Unlock()
230231
clearBuffer(e.buf[:])
231232
if _, err := e.f.ReadAt(e.buf[:], offOffset); err != nil {
232233
return 0, err
233234
}
234-
// Since the block offset is relative from its location + size of index
235-
// value (8), we need to add it to it's offset to get the block's
236-
// absolute offset.
237-
return offOffset + 8 + int64(binary.LittleEndian.Uint64(e.buf[:])), nil
235+
// Since the block offset is relative from the start of the block index record
236+
// we need to add the record offset to it's offset to get the block's absolute
237+
// offset.
238+
return blockIndexRecordOffset + int64(binary.LittleEndian.Uint64(e.buf[:])), nil
238239
}
239240

240241
// newReader returns a snappy.Reader for the e2store entry value at off.

0 commit comments

Comments
 (0)