Skip to content

Commit 88e2caa

Browse files
committed
core: change to one callback per batch of inserted headers + review concerns
1 parent b58fe2d commit 88e2caa

File tree

2 files changed

+27
-35
lines changed

2 files changed

+27
-35
lines changed

core/headerchain.go

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 {
132132
type headerWriteResult struct {
133133
ignored int
134134
imported int
135-
status WriteStatus
136135
lastHash common.Hash
137136
lastHeader *types.Header
138137
}
@@ -155,12 +154,12 @@ func (hc *HeaderChain) WriteHeaders(headers []*types.Header, postWriteFn PostWri
155154
return &headerWriteResult{}, consensus.ErrUnknownAncestor
156155
}
157156
var (
158-
lastHeader *types.Header // Last successfully imported header
159-
lastNumber uint64 // Last successfully imported number
160-
lastHash common.Hash
161-
externTd *big.Int // TD of successfully imported chain
162-
inserted []numberHash // Ephemeral lookup of number/hash for the chain
163-
firstInsertedIndex = -1 // Index of the first non-ignored header
157+
lastHeader *types.Header // Last successfully imported header
158+
lastNumber uint64 // Last successfully imported number
159+
lastHash common.Hash
160+
externTd *big.Int // TD of successfully imported chain
161+
inserted []numberHash // Ephemeral lookup of number/hash for the chain
162+
firstInserted = -1 // Index of the first non-ignored header
164163
)
165164
lastHash, lastNumber = headers[0].ParentHash, headers[0].Number.Uint64()-1 // Already validated above
166165
batch := hc.chainDb.NewBatch()
@@ -178,7 +177,7 @@ func (hc *HeaderChain) WriteHeaders(headers []*types.Header, postWriteFn PostWri
178177
}
179178
hash, number := header.Hash(), header.Number.Uint64()
180179
if header.ParentHash != lastHash {
181-
log.Warn("Non-contiguous header insertion", "header.parent", header.ParentHash, "expected", hash, "number", number)
180+
log.Warn("Non-contiguous header insertion", "parent", header.ParentHash, "expected", lastHash, "number", number)
182181
break
183182
}
184183
externTd = new(big.Int).Add(header.Difficulty, ptd)
@@ -193,8 +192,8 @@ func (hc *HeaderChain) WriteHeaders(headers []*types.Header, postWriteFn PostWri
193192
inserted = append(inserted, numberHash{number, hash})
194193
hc.headerCache.Add(hash, header)
195194
hc.numberCache.Add(hash, number)
196-
if firstInsertedIndex < 0 {
197-
firstInsertedIndex = i
195+
if firstInserted < 0 {
196+
firstInserted = i
198197
}
199198
}
200199
lastHeader, lastHash, lastNumber, ptd = header, hash, number, externTd
@@ -253,7 +252,7 @@ func (hc *HeaderChain) WriteHeaders(headers []*types.Header, postWriteFn PostWri
253252
// during this import batch, then we need to write that now
254253
// Further down, we continue writing the staus for the ones that
255254
// were not already known
256-
for i := 0; i < firstInsertedIndex; i++ {
255+
for i := 0; i < firstInserted; i++ {
257256
hash := headers[i].Hash()
258257
num := headers[i].Number.Uint64()
259258
rawdb.WriteCanonicalHash(markerBatch, hash, num)
@@ -279,30 +278,23 @@ func (hc *HeaderChain) WriteHeaders(headers []*types.Header, postWriteFn PostWri
279278
// Execute any post-write callback function
280279
// - unless we're exiting
281280
// - and unless we ignored everything
282-
if postWriteFn != nil && !hc.procInterrupt() && firstInsertedIndex >= 0 {
283-
// TODO: Is it really necessary to invoke this N times, instead of just
284-
// invoking it for the last header?
285-
// It is only used for lightchain event aggregation
286-
for _, header := range headers[firstInsertedIndex:] {
287-
if header.Number.Uint64() > lastNumber {
288-
break
289-
}
290-
postWriteFn(header, status)
291-
}
281+
if postWriteFn != nil && !hc.procInterrupt() && len(inserted) > 0 {
282+
// The postwrite function is called only for the last imported header.
283+
// It is only used for lightchain event aggregation.
284+
postWriteFn(lastHeader, status)
292285
}
293286
return &headerWriteResult{
294287
ignored: len(headers) - len(inserted),
295288
imported: len(inserted),
296-
status: status,
297289
lastHash: lastHash,
298290
lastHeader: lastHeader,
299291
}, nil
300292
}
301293

302294
// PostWriteCallback is a callback function for inserting headers,
303-
// which is called after each header is inserted.
304-
// The reson for having it is:
305-
// In light-chain mode, status should be processed and light chain events sent,
295+
// which is called once, with the last successfully imported header in the batch.
296+
// The raeson for having it is:
297+
// In light-chain mode, status should be processed and light chain events sent,
306298
// whereas in a non-light mode this is not necessary since chain events are sent after inserting blocks.
307299
type PostWriteCallback func(header *types.Header, status WriteStatus)
308300

core/headerchain_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,43 +98,43 @@ func TestHeaderInsertion(t *testing.T) {
9898
log.Root().SetHandler(log.StdoutHandler)
9999

100100
// Inserting 64 headers on an empty chain, expecting
101-
// 64 callbacks, 64 canon-status, 0 sidestatus,
102-
if err := testInsert(t, hc, chainA[:64], 64, 64, 0); err != nil {
101+
// 1 callbacks, 1 canon-status, 0 sidestatus,
102+
if err := testInsert(t, hc, chainA[:64], 1, 1, 0); err != nil {
103103
t.Fatal(err)
104104
}
105105

106-
// Inserting 64 inentical headers, expecting
106+
// Inserting 64 identical headers, expecting
107107
// 0 callbacks, 0 canon-status, 0 sidestatus,
108108
if err := testInsert(t, hc, chainA[:64], 0, 0, 0); err != nil {
109109
t.Fatal(err)
110110
}
111111
// Inserting the same some old, some new headers
112-
// 32 callbacks, 32 canon, 0 side
113-
if err := testInsert(t, hc, chainA[32:96], 32, 32, 0); err != nil {
112+
// 1 callbacks, 1 canon, 0 side
113+
if err := testInsert(t, hc, chainA[32:96], 1, 1, 0); err != nil {
114114
t.Fatal(err)
115115
}
116116
// Inserting side blocks, but not overtaking the canon chain
117-
if err := testInsert(t, hc, chainB[0:32], 32, 0, 32); err != nil {
117+
if err := testInsert(t, hc, chainB[0:32], 1, 0, 1); err != nil {
118118
t.Fatal(err)
119119
}
120120
// Inserting more side blocks, but we don't have the parent
121121
if err := testInsert(t, hc, chainB[34:36], 0, 0, 0); !errors.Is(err, consensus.ErrUnknownAncestor) {
122122
t.Fatal(fmt.Errorf("Expected %v, got %v", consensus.ErrUnknownAncestor, err))
123123
}
124124
// Inserting more sideblocks, overtaking the canon chain
125-
if err := testInsert(t, hc, chainB[32:97], 65, 65, 0); err != nil {
125+
if err := testInsert(t, hc, chainB[32:97], 1, 1, 0); err != nil {
126126
t.Fatal(err)
127127
}
128128
// Inserting more A-headers, taking back the canonicality
129-
if err := testInsert(t, hc, chainA[90:100], 4, 4, 0); err != nil {
129+
if err := testInsert(t, hc, chainA[90:100], 1, 1, 0); err != nil {
130130
t.Fatal(err)
131131
}
132132
// And B becomes canon again
133-
if err := testInsert(t, hc, chainB[97:107], 10, 10, 0); err != nil {
133+
if err := testInsert(t, hc, chainB[97:107], 1, 1, 0); err != nil {
134134
t.Fatal(err)
135135
}
136136
// And B becomes even longer
137-
if err := testInsert(t, hc, chainB[107:128], 21, 21, 0); err != nil {
137+
if err := testInsert(t, hc, chainB[107:128], 1, 1, 0); err != nil {
138138
t.Fatal(err)
139139
}
140140
}

0 commit comments

Comments
 (0)