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,15 +131,17 @@ 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
sm.execTraceCacheLock.Lock() if defaultExecTraceCacheSize > 0 {
if entry, ok := sm.execTraceCache.Get(tsKey); ok { sm.execTraceCacheLock.Lock()
// we have to make a deep copy since caller can modify the invocTrace if entry, ok := sm.execTraceCache.Get(tsKey); ok {
// and we don't want that to change what we store in cache // we have to make a deep copy since caller can modify the invocTrace
invocTraceCopy := makeDeepCopy(entry.invocTrace) // and we don't want that to change what we store in cache
invocTraceCopy := makeDeepCopy(entry.invocTrace)
sm.execTraceCacheLock.Unlock()
return entry.postStateRoot, invocTraceCopy, nil
}
sm.execTraceCacheLock.Unlock() sm.execTraceCacheLock.Unlock()
return entry.postStateRoot, invocTraceCopy, nil
} }
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
} }
invocTraceCopy := makeDeepCopy(invocTrace) if defaultExecTraceCacheSize > 0 {
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,9 +212,14 @@ func NewStateManager(cs *store.ChainStore, exec Executor, sys vm.SyscallBuilder,
} }
} }
execTraceCache, err := lru.NewARC[types.TipSetKey, tipSetCacheEntry](execTraceCacheSize) log.Debugf("execTraceCache size: %d", defaultExecTraceCacheSize)
if err != nil { var execTraceCache *lru.ARCCache[types.TipSetKey, tipSetCacheEntry]
return nil, err var err error
if defaultExecTraceCacheSize > 0 {
execTraceCache, err = lru.NewARC[types.TipSetKey, tipSetCacheEntry](defaultExecTraceCacheSize)
if err != nil {
return nil, err
}
} }
return &StateManager{ return &StateManager{