Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

recordingdb: add config, trie flush, and metrics #240

Merged
merged 2 commits into from
Jul 10, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 39 additions & 3 deletions arbitrum/recordingdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,15 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
flag "github.com/spf13/pflag"
)

var (
recordingDbSize = metrics.NewRegisteredGauge("arb/validator/recordingdb/size", nil) // note: only updating when adding state, not when removing - but should be good enough
recordingDbReferences = metrics.NewRegisteredGauge("arb/validator/recordingdb/references", nil)
)

type RecordingKV struct {
Expand Down Expand Up @@ -151,17 +158,34 @@ func (r *RecordingChainContext) GetMinBlockNumberAccessed() uint64 {
return r.minBlockNumberAccessed
}

type RecordingDatabaseConfig struct {
TrieDirtyCache int `koanf:"trie-dirty-cache"`
TrieCleanCache int `koanf:"trie-clean-cache"`
}

var DefaultRecordingDatabaseConfig = RecordingDatabaseConfig{
TrieDirtyCache: 1024,
TrieCleanCache: 16,
}

func RecordingDatabaseConfigAddOptions(prefix string, f *flag.FlagSet) {
f.Int(prefix+".trie-dirty-cache", DefaultRecordingDatabaseConfig.TrieDirtyCache, "like trie-dirty-cache for the separate, recording database (used for validation)")
f.Int(prefix+".trie-clean-cache", DefaultRecordingDatabaseConfig.TrieCleanCache, "like trie-clean-cache for the separate, recording database (used for validation)")
}

type RecordingDatabase struct {
config *RecordingDatabaseConfig
db state.Database
bc *core.BlockChain
mutex sync.Mutex // protects StateFor and Dereference
references int64
}

func NewRecordingDatabase(ethdb ethdb.Database, blockchain *core.BlockChain) *RecordingDatabase {
func NewRecordingDatabase(config *RecordingDatabaseConfig, ethdb ethdb.Database, blockchain *core.BlockChain) *RecordingDatabase {
return &RecordingDatabase{
db: state.NewDatabaseWithConfig(ethdb, &trie.Config{Cache: 16}), //TODO cache needed? configurable?
bc: blockchain,
config: config,
db: state.NewDatabaseWithConfig(ethdb, &trie.Config{Cache: config.TrieCleanCache}),
bc: blockchain,
}
}

Expand Down Expand Up @@ -194,13 +218,15 @@ func (r *RecordingDatabase) WriteStateToDatabase(header *types.Header) error {
// lock must be held when calling that
func (r *RecordingDatabase) referenceRootLockHeld(root common.Hash) {
r.references++
recordingDbReferences.Update(r.references)
r.db.TrieDB().Reference(root, common.Hash{})
}

func (r *RecordingDatabase) dereferenceRoot(root common.Hash) {
r.mutex.Lock()
defer r.mutex.Unlock()
r.references--
recordingDbReferences.Update(r.references)
r.db.TrieDB().Dereference(root)
}

Expand All @@ -215,6 +241,16 @@ func (r *RecordingDatabase) addStateVerify(statedb *state.StateDB, expected comm
return fmt.Errorf("bad root hash expected: %v got: %v", expected, result)
}
r.referenceRootLockHeld(result)

size, _ := r.db.TrieDB().Size()
limit := common.StorageSize(r.config.TrieDirtyCache) * 1024 * 1024
recordingDbSize.Update(int64(size))
if size > limit {
log.Info("Recording DB: flushing to disk", "size", size, "limit", limit)
r.db.TrieDB().Cap(limit - ethdb.IdealBatchSize)
size, _ = r.db.TrieDB().Size()
recordingDbSize.Update(int64(size))
}
return nil
}

Expand Down