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.
This commit is contained in:
Austin Roberts 2021-10-28 20:41:32 -05:00
parent 4acf8d22df
commit 80ae5b46d4

View File

@ -37,77 +37,83 @@ func PluginCommitUpdate(pl *plugins.PluginLoader, num uint64) {
lock.Lock() lock.Lock()
defer lock.Unlock() defer lock.Unlock()
if freezerUpdates == nil { freezerUpdates = make(map[uint64]map[string]interface{}) } if freezerUpdates == nil { freezerUpdates = make(map[uint64]map[string]interface{}) }
defer func() { delete(freezerUpdates, num) }() min := ^uint64(0)
update, ok := freezerUpdates[num] for i := range freezerUpdates{
if !ok { if min < i { min = i }
log.Warn("Attempting to commit untracked block", "num", num)
return
} }
fnList := pl.Lookup("ModifyAncients", func(item interface{}) bool { for i := min ; i < num; i++ {
_, ok := item.(func(uint64, map[string]interface{})) update, ok := freezerUpdates[i]
return ok defer func() { delete(freezerUpdates, i) }()
}) if !ok {
for _, fni := range fnList { log.Warn("Attempting to commit untracked block", "num", i)
if fn, ok := fni.(func(uint64, map[string]interface{})); ok { continue
fn(num, update)
} }
} fnList := pl.Lookup("ModifyAncients", func(item interface{}) bool {
appendAncientFnList := pl.Lookup("AppendAncient", func(item interface{}) bool { _, ok := item.(func(uint64, map[string]interface{}))
_, ok := item.(func(number uint64, hash, header, body, receipts, td []byte)) return ok
if ok { log.Warn("PlugEth's AppendAncient is deprecated. Please update to ModifyAncients.") } })
return ok for _, fni := range fnList {
}) if fn, ok := fni.(func(uint64, map[string]interface{})); ok {
if len(appendAncientFnList) > 0 { fn(i, update)
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 headeri, ok := update[freezerHeaderTable]; ok { appendAncientFnList := pl.Lookup("AppendAncient", func(item interface{}) bool {
switch v := headeri.(type) { _, ok := item.(func(number uint64, hash, header, body, receipts, td []byte))
case []byte: if ok { log.Warn("PlugEth's AppendAncient is deprecated. Please update to ModifyAncients.") }
header = v return ok
default: })
header, _ = rlp.EncodeToBytes(v) 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 headeri, ok := update[freezerHeaderTable]; ok {
if bodyi, ok := update[freezerBodiesTable]; ok { switch v := headeri.(type) {
switch v := bodyi.(type) { case []byte:
case []byte: header = v
body = v default:
default: header, _ = rlp.EncodeToBytes(v)
body, _ = rlp.EncodeToBytes(v) }
} }
} if bodyi, ok := update[freezerBodiesTable]; ok {
if receiptsi, ok := update[freezerReceiptTable]; ok { switch v := bodyi.(type) {
switch v := receiptsi.(type) { case []byte:
case []byte: body = v
receipts = v default:
default: body, _ = rlp.EncodeToBytes(v)
receipts, _ = rlp.EncodeToBytes(v) }
} }
} if receiptsi, ok := update[freezerReceiptTable]; ok {
if tdi, ok := update[freezerDifficultyTable]; ok { switch v := receiptsi.(type) {
switch v := tdi.(type) { case []byte:
case []byte: receipts = v
td = v default:
default: receipts, _ = rlp.EncodeToBytes(v)
td, _ = rlp.EncodeToBytes(v) }
} }
} if tdi, ok := update[freezerDifficultyTable]; ok {
for _, fni := range appendAncientFnList { switch v := tdi.(type) {
if fn, ok := fni.(func(number uint64, hash, header, body, receipts, td []byte)); ok { case []byte:
fn(num, hash, header, body, receipts, td) 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)
}
} }
} }
} }