From 149b5220ad421a54320ffaccdababc4e711c0792 Mon Sep 17 00:00:00 2001 From: Austin Roberts Date: Mon, 18 Oct 2021 12:35:56 -0500 Subject: [PATCH] Update plugin hooks to support AppendAncient changes This commit adds a ModifyAncients hook that plugins can implement to more accurately track what Geth is doing under the hood. We still support the old AppendAncients interface as best we can, though internal changes may make it so that it does not behave as it once did. --- core/rawdb/freezer.go | 1 + core/rawdb/freezer_batch.go | 2 + core/rawdb/plugin_hooks.go | 121 ++++++++++++++++++++++++++++++------ 3 files changed, 106 insertions(+), 18 deletions(-) diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index 4cecbc50f..d75ee4f00 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -261,6 +261,7 @@ func (f *freezer) ModifyAncients(fn func(ethdb.AncientWriteOp) error) (writeSize if err != nil { return 0, err } + pluginCommitUpdate(item) atomic.StoreUint64(&f.frozen, item) return writeSize, nil } diff --git a/core/rawdb/freezer_batch.go b/core/rawdb/freezer_batch.go index 8297c0ac1..066fba5bc 100644 --- a/core/rawdb/freezer_batch.go +++ b/core/rawdb/freezer_batch.go @@ -44,11 +44,13 @@ func newFreezerBatch(f *freezer) *freezerBatch { // Append adds an RLP-encoded item of the given kind. func (batch *freezerBatch) Append(kind string, num uint64, item interface{}) error { + PluginTrackUpdate(num, kind, item) return batch.tables[kind].Append(num, item) } // AppendRaw adds an item of the given kind. func (batch *freezerBatch) AppendRaw(kind string, num uint64, item []byte) error { + PluginTrackUpdate(num, kind, item) return batch.tables[kind].AppendRaw(num, item) } diff --git a/core/rawdb/plugin_hooks.go b/core/rawdb/plugin_hooks.go index 9daac9327..4cf7f66f1 100644 --- a/core/rawdb/plugin_hooks.go +++ b/core/rawdb/plugin_hooks.go @@ -2,25 +2,110 @@ package rawdb import ( - "github.com/ethereum/go-ethereum/plugins" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/plugins" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" ) -func PluginAppendAncient(pl *plugins.PluginLoader, number uint64, hash, header, body, receipts, td []byte) { - fnList := pl.Lookup("AppendAncient", func(item interface{}) bool { - _, ok := item.(func(number uint64, hash, header, body, receipts, td []byte)) - return ok - }) - for _, fni := range fnList { - if fn, ok := fni.(func(number uint64, hash, header, body, receipts, td []byte)); ok { - fn(number, hash, header, body, receipts, td) - } - } +var ( + freezerUpdates map[uint64]map[string]interface{} +) + +func PluginTrackUpdate(num uint64, kind string, value interface{}) { + update, ok := freezerUpdates[num] + if !ok { + update = make(map[string]interface{}) + freezerUpdates[num] = update + } + update[kind] = value } -func pluginAppendAncient(number uint64, hash, header, body, receipts, td []byte) { - if plugins.DefaultPluginLoader == nil { - log.Warn("Attempting AppendAncient, but default PluginLoader has not been initialized") - return - } - PluginAppendAncient(plugins.DefaultPluginLoader, number, hash, header, body, receipts, td) + +func PluginResetUpdate(num uint64) { + delete(freezerUpdates, num) +} + + +func pluginCommitUpdate(num uint64) { + if plugins.DefaultPluginLoader == nil { + log.Warn("Attempting CommitUpdate, but default PluginLoader has not been initialized") + return + } + PluginCommitUpdate(plugins.DefaultPluginLoader, num) +} + +func PluginCommitUpdate(pl *plugins.PluginLoader, num uint64) { + defer func() { delete(freezerUpdates, num) }() + update, ok := freezerUpdates[num] + if !ok { + log.Warn("Attempting to commit untracked block", "num", num) + return + } + 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) + } + } + 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 headeri, ok := update[freezerHeaderTable]; ok { + switch v := headeri.(type) { + case []byte: + header = v + default: + header, _ = rlp.EncodeToBytes(v) + } + } + if bodyi, ok := update[freezerBodiesTable]; ok { + switch v := bodyi.(type) { + case []byte: + body = v + default: + body, _ = rlp.EncodeToBytes(v) + } + } + if receiptsi, ok := update[freezerReceiptTable]; ok { + switch v := receiptsi.(type) { + case []byte: + receipts = v + default: + receipts, _ = rlp.EncodeToBytes(v) + } + } + 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(num, hash, header, body, receipts, td) + } + } + } }