diff --git a/core/blockchain.go b/core/blockchain.go index 0d95cee7e..b31f915bc 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1384,6 +1384,11 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. chosen := current - TriesInMemory flushInterval := time.Duration(atomic.LoadInt64(&bc.flushInterval)) // If we exceeded time allowance, flush an entire trie to disk + + // begin PluGeth code injection + flushInterval = pluginSetTrieFlushIntervalClone(flushInterval) + // end PluGeth code injection + if bc.gcproc > flushInterval { // If the header is missing (canonical chain behind), we're reorging a low // diff sidechain. Suspend committing until this operation is completed. diff --git a/core/plugin_hooks.go b/core/plugin_hooks.go index 2324f4ae2..f00730bdd 100644 --- a/core/plugin_hooks.go +++ b/core/plugin_hooks.go @@ -4,6 +4,8 @@ import ( "encoding/json" "math/big" "reflect" + "time" + "sync" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" @@ -297,3 +299,28 @@ func pluginGetBlockTracer(hash common.Hash, statedb *state.StateDB) (*metaTracer } return PluginGetBlockTracer(plugins.DefaultPluginLoader, hash, statedb) } + +func PluginSetTrieFlushIntervalClone(pl *plugins.PluginLoader, flushInterval time.Duration) time.Duration { + fnList := pl.Lookup("SetTrieFlushIntervalClone", func(item interface{}) bool{ + _, ok := item.(func(time.Duration) time.Duration) + return ok + }) + var snc sync.Once + if len(fnList) > 1 { + snc.Do(func() {log.Warn("The blockChain flushInterval value is being accessed by multiple plugins")}) + } + for _, fni := range fnList { + if fn, ok := fni.(func(time.Duration) time.Duration); ok { + flushInterval = fn(flushInterval) + } + } + return flushInterval +} + +func pluginSetTrieFlushIntervalClone(flushInterval time.Duration) time.Duration { + if plugins.DefaultPluginLoader == nil { + log.Warn("Attempting setTreiFlushIntervalClone, but default PluginLoader has not been initialized") + return flushInterval + } + return PluginSetTrieFlushIntervalClone(plugins.DefaultPluginLoader, flushInterval) +} \ No newline at end of file diff --git a/go.sum b/go.sum index 9cd5a09f6..31a8f0b22 100644 --- a/go.sum +++ b/go.sum @@ -291,6 +291,7 @@ github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpx github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= diff --git a/trie/database.go b/trie/database.go index 895ffdf89..5b55293b2 100644 --- a/trie/database.go +++ b/trie/database.go @@ -637,6 +637,11 @@ func (db *Database) Commit(node common.Hash, report bool) error { // outside code doesn't see an inconsistent state (referenced data removed from // memory cache during commit but not yet in persistent storage). This is ensured // by only uncaching existing data when the database write finalizes. + + // begin PluGeth injection + pluginPreTrieCommit(node) + // end PluGeth injection + start := time.Now() batch := db.diskdb.NewBatch() @@ -683,6 +688,10 @@ func (db *Database) Commit(node common.Hash, report bool) error { db.gcnodes, db.gcsize, db.gctime = 0, 0, 0 db.flushnodes, db.flushsize, db.flushtime = 0, 0, 0 + // begin PluGeth injection + pluginPostTrieCommit(node) + // end PluGeth injection + return nil } diff --git a/trie/plugin_hooks.go b/trie/plugin_hooks.go new file mode 100644 index 000000000..1ef11c60c --- /dev/null +++ b/trie/plugin_hooks.go @@ -0,0 +1,48 @@ +package trie + +import ( + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/plugins" + "github.com/ethereum/go-ethereum/common" + "github.com/openrelayxyz/plugeth-utils/core" +) + +func PluginPreTrieCommit(pl *plugins.PluginLoader, node common.Hash) { + fnList := pl.Lookup("PreTrieCommit", func(item interface{}) bool { + _, ok := item.(func(core.Hash)) + return ok + }) + for _, fni := range fnList { + if fn, ok := fni.(func(core.Hash)); ok { + fn(core.Hash(node)) + } + } +} + +func pluginPreTrieCommit(node common.Hash) { + if plugins.DefaultPluginLoader == nil { + log.Warn("Attempting PreTrieCommit, but default PluginLoader has not been initialized") + return + } + PluginPreTrieCommit(plugins.DefaultPluginLoader, node) +} + +func PluginPostTrieCommit(pl *plugins.PluginLoader, node common.Hash) { + fnList := pl.Lookup("PostTrieCommit", func(item interface{}) bool { + _, ok := item.(func(core.Hash)) + return ok + }) + for _, fni := range fnList { + if fn, ok := fni.(func(core.Hash)); ok { + fn(core.Hash(node)) + } + } +} + +func pluginPostTrieCommit(node common.Hash) { + if plugins.DefaultPluginLoader == nil { + log.Warn("Attempting PostTrieCommit, but default PluginLoader has not been initialized") + return + } + PluginPostTrieCommit(plugins.DefaultPluginLoader, node) +}