From 80ae5b46d40fab556b53034887c4d62c9cf9d010 Mon Sep 17 00:00:00 2001 From: Austin Roberts Date: Thu, 28 Oct 2021 20:41:32 -0500 Subject: [PATCH] Fix tracking of ancients We had been assuming that the `item` returned from batch.commit() was the item committed, but it's actually the next item to be added to the freezer, and multiple items can be committed in a single batch. This commit finds the smallest item in the freezer and iterates from that to the number returned by commit(), passing any tracked blocks in that range to plugins. --- core/rawdb/plugin_hooks.go | 132 +++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 63 deletions(-) diff --git a/core/rawdb/plugin_hooks.go b/core/rawdb/plugin_hooks.go index 40466be93..1845408cb 100644 --- a/core/rawdb/plugin_hooks.go +++ b/core/rawdb/plugin_hooks.go @@ -37,77 +37,83 @@ func PluginCommitUpdate(pl *plugins.PluginLoader, num uint64) { lock.Lock() defer lock.Unlock() if freezerUpdates == nil { freezerUpdates = make(map[uint64]map[string]interface{}) } - defer func() { delete(freezerUpdates, num) }() - update, ok := freezerUpdates[num] - if !ok { - log.Warn("Attempting to commit untracked block", "num", num) - return + min := ^uint64(0) + for i := range freezerUpdates{ + if min < i { min = i } } - fnList := pl.Lookup("ModifyAncients", func(item interface{}) bool { - _, ok := item.(func(uint64, map[string]interface{})) - return ok - }) - for _, fni := range fnList { - if fn, ok := fni.(func(uint64, map[string]interface{})); ok { - fn(num, update) + for i := min ; i < num; i++ { + update, ok := freezerUpdates[i] + defer func() { delete(freezerUpdates, i) }() + if !ok { + log.Warn("Attempting to commit untracked block", "num", i) + continue } - } - appendAncientFnList := pl.Lookup("AppendAncient", func(item interface{}) bool { - _, ok := item.(func(number uint64, hash, header, body, receipts, td []byte)) - if ok { log.Warn("PlugEth's AppendAncient is deprecated. Please update to ModifyAncients.") } - return ok - }) - if len(appendAncientFnList) > 0 { - var ( - hash []byte - header []byte - body []byte - receipts []byte - td []byte - ) - if hashi, ok := update[freezerHashTable]; ok { - switch v := hashi.(type) { - case []byte: - hash = v - default: - hash, _ = rlp.EncodeToBytes(v) + fnList := pl.Lookup("ModifyAncients", func(item interface{}) bool { + _, ok := item.(func(uint64, map[string]interface{})) + return ok + }) + for _, fni := range fnList { + if fn, ok := fni.(func(uint64, map[string]interface{})); ok { + fn(i, update) } } - if headeri, ok := update[freezerHeaderTable]; ok { - switch v := headeri.(type) { - case []byte: - header = v - default: - header, _ = rlp.EncodeToBytes(v) + appendAncientFnList := pl.Lookup("AppendAncient", func(item interface{}) bool { + _, ok := item.(func(number uint64, hash, header, body, receipts, td []byte)) + if ok { log.Warn("PlugEth's AppendAncient is deprecated. Please update to ModifyAncients.") } + return ok + }) + if len(appendAncientFnList) > 0 { + var ( + hash []byte + header []byte + body []byte + receipts []byte + td []byte + ) + if hashi, ok := update[freezerHashTable]; ok { + switch v := hashi.(type) { + case []byte: + hash = v + default: + hash, _ = rlp.EncodeToBytes(v) + } } - } - if bodyi, ok := update[freezerBodiesTable]; ok { - switch v := bodyi.(type) { - case []byte: - body = v - default: - body, _ = rlp.EncodeToBytes(v) + if headeri, ok := update[freezerHeaderTable]; ok { + switch v := headeri.(type) { + case []byte: + header = v + default: + header, _ = rlp.EncodeToBytes(v) + } } - } - if receiptsi, ok := update[freezerReceiptTable]; ok { - switch v := receiptsi.(type) { - case []byte: - receipts = v - default: - receipts, _ = rlp.EncodeToBytes(v) + if bodyi, ok := update[freezerBodiesTable]; ok { + switch v := bodyi.(type) { + case []byte: + body = v + default: + body, _ = rlp.EncodeToBytes(v) + } } - } - if tdi, ok := update[freezerDifficultyTable]; ok { - switch v := tdi.(type) { - case []byte: - td = v - default: - td, _ = rlp.EncodeToBytes(v) + if receiptsi, ok := update[freezerReceiptTable]; ok { + switch v := receiptsi.(type) { + case []byte: + receipts = v + default: + receipts, _ = rlp.EncodeToBytes(v) + } } - } - for _, fni := range appendAncientFnList { - if fn, ok := fni.(func(number uint64, hash, header, body, receipts, td []byte)); ok { - fn(num, hash, header, body, receipts, td) + if tdi, ok := update[freezerDifficultyTable]; ok { + switch v := tdi.(type) { + case []byte: + td = v + default: + td, _ = rlp.EncodeToBytes(v) + } + } + for _, fni := range appendAncientFnList { + if fn, ok := fni.(func(number uint64, hash, header, body, receipts, td []byte)); ok { + fn(i, hash, header, body, receipts, td) + } } } }