Make execution trace configurable via env variable

We want to make the execution trace cache size configurable as SPs
may want to disable it while exchanges may want to crank it up.

We were also are going with intuition for this value, so having
ability to change it without a new build would help.

Fixes: https://github.com/filecoin-project/lotus/issues/10584
This commit is contained in:
Fridrik Asmundsson 2023-03-29 11:38:26 +02:00
parent 841b7b8730
commit 17505a0022
2 changed files with 37 additions and 16 deletions

View File

@ -131,6 +131,7 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c
tsKey := ts.Key() tsKey := ts.Key()
// check if we have the trace for this tipset in the cache // check if we have the trace for this tipset in the cache
if defaultExecTraceCacheSize > 0 {
sm.execTraceCacheLock.Lock() sm.execTraceCacheLock.Lock()
if entry, ok := sm.execTraceCache.Get(tsKey); ok { if entry, ok := sm.execTraceCache.Get(tsKey); ok {
// we have to make a deep copy since caller can modify the invocTrace // we have to make a deep copy since caller can modify the invocTrace
@ -140,6 +141,7 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c
return entry.postStateRoot, invocTraceCopy, nil return entry.postStateRoot, invocTraceCopy, nil
} }
sm.execTraceCacheLock.Unlock() sm.execTraceCacheLock.Unlock()
}
var invocTrace []*api.InvocResult var invocTrace []*api.InvocResult
st, err := sm.ExecutionTraceWithMonitor(ctx, ts, &InvocationTracer{trace: &invocTrace}) st, err := sm.ExecutionTraceWithMonitor(ctx, ts, &InvocationTracer{trace: &invocTrace})
@ -147,11 +149,13 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c
return cid.Undef, nil, err return cid.Undef, nil, err
} }
if defaultExecTraceCacheSize > 0 {
invocTraceCopy := makeDeepCopy(invocTrace) invocTraceCopy := makeDeepCopy(invocTrace)
sm.execTraceCacheLock.Lock() sm.execTraceCacheLock.Lock()
sm.execTraceCache.Add(tsKey, tipSetCacheEntry{st, invocTraceCopy}) sm.execTraceCache.Add(tsKey, tipSetCacheEntry{st, invocTraceCopy})
sm.execTraceCacheLock.Unlock() sm.execTraceCacheLock.Unlock()
}
return st, invocTrace, nil return st, invocTrace, nil
} }

View File

@ -3,6 +3,8 @@ package stmgr
import ( import (
"context" "context"
"fmt" "fmt"
"os"
"strconv"
"sync" "sync"
lru "github.com/hashicorp/golang-lru/v2" lru "github.com/hashicorp/golang-lru/v2"
@ -40,8 +42,7 @@ import (
const LookbackNoLimit = api.LookbackNoLimit const LookbackNoLimit = api.LookbackNoLimit
const ReceiptAmtBitwidth = 3 const ReceiptAmtBitwidth = 3
const execTraceCacheSize = 16 var defaultExecTraceCacheSize = 16
var log = logging.Logger("statemgr") var log = logging.Logger("statemgr")
type StateManagerAPI interface { type StateManagerAPI interface {
@ -74,6 +75,17 @@ func (m *migrationResultCache) keyForMigration(root cid.Cid) dstore.Key {
return dstore.NewKey(kStr) return dstore.NewKey(kStr)
} }
func init() {
if s := os.Getenv("LOTUS_EXEC_TRACE_CACHE"); s != "" {
letc, err := strconv.Atoi(s)
if err != nil {
log.Errorf("failed to parse 'LOTUS_EXEC_TRACE_CACHE' env var: %s", err)
}
defaultExecTraceCacheSize = letc
}
}
func (m *migrationResultCache) Get(ctx context.Context, root cid.Cid) (cid.Cid, bool, error) { func (m *migrationResultCache) Get(ctx context.Context, root cid.Cid) (cid.Cid, bool, error) {
k := m.keyForMigration(root) k := m.keyForMigration(root)
@ -200,10 +212,15 @@ func NewStateManager(cs *store.ChainStore, exec Executor, sys vm.SyscallBuilder,
} }
} }
execTraceCache, err := lru.NewARC[types.TipSetKey, tipSetCacheEntry](execTraceCacheSize) log.Debugf("execTraceCache size: %d", defaultExecTraceCacheSize)
var execTraceCache *lru.ARCCache[types.TipSetKey, tipSetCacheEntry]
var err error
if defaultExecTraceCacheSize > 0 {
execTraceCache, err = lru.NewARC[types.TipSetKey, tipSetCacheEntry](defaultExecTraceCacheSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
}
return &StateManager{ return &StateManager{
networkVersions: networkVersions, networkVersions: networkVersions,