Commit eb1c9b30 authored by refcell's avatar refcell Committed by GitHub

feat(op-challenger): Parallelize Agent Actions (#9804)

* feat(op-challenger): Place agent actions behind a synced wait group

* op-challenger: Split out individual action into a separate method to reduce nesting.

---------
Co-authored-by: default avatarAdrian Sutton <adrian@oplabs.co>
parent 47a1478a
...@@ -67,49 +67,56 @@ func (a *Agent) Act(ctx context.Context) error { ...@@ -67,49 +67,56 @@ func (a *Agent) Act(ctx context.Context) error {
if a.tryResolve(ctx) { if a.tryResolve(ctx) {
return nil return nil
} }
game, err := a.newGameFromContracts(ctx) game, err := a.newGameFromContracts(ctx)
if err != nil { if err != nil {
return fmt.Errorf("create game from contracts: %w", err) return fmt.Errorf("create game from contracts: %w", err)
} }
// Calculate the actions to take
actions, err := a.solver.CalculateNextActions(ctx, game) actions, err := a.solver.CalculateNextActions(ctx, game)
if err != nil { if err != nil {
a.log.Error("Failed to calculate all required moves", "err", err) a.log.Error("Failed to calculate all required moves", "err", err)
} }
// Perform the actions var wg sync.WaitGroup
wg.Add(len(actions))
for _, action := range actions { for _, action := range actions {
actionLog := a.log.New("action", action.Type, "is_attack", action.IsAttack, "parent", action.ParentIdx) go a.performAction(ctx, &wg, action)
if action.Type == types.ActionTypeStep { }
containsOracleData := action.OracleData != nil wg.Wait()
isLocal := containsOracleData && action.OracleData.IsLocal return nil
actionLog = actionLog.New( }
"prestate", common.Bytes2Hex(action.PreState),
"proof", common.Bytes2Hex(action.ProofData),
"containsOracleData", containsOracleData,
"isLocalPreimage", isLocal,
)
if action.OracleData != nil {
actionLog = actionLog.New("oracleKey", common.Bytes2Hex(action.OracleData.OracleKey))
}
} else {
actionLog = actionLog.New("value", action.Value)
}
switch action.Type { func (a *Agent) performAction(ctx context.Context, wg *sync.WaitGroup, action types.Action) {
case types.ActionTypeMove: defer wg.Done()
a.metrics.RecordGameMove() actionLog := a.log.New("action", action.Type, "is_attack", action.IsAttack, "parent", action.ParentIdx)
case types.ActionTypeStep: if action.Type == types.ActionTypeStep {
a.metrics.RecordGameStep() containsOracleData := action.OracleData != nil
} isLocal := containsOracleData && action.OracleData.IsLocal
actionLog.Info("Performing action") actionLog = actionLog.New(
err := a.responder.PerformAction(ctx, action) "prestate", common.Bytes2Hex(action.PreState),
if err != nil { "proof", common.Bytes2Hex(action.ProofData),
actionLog.Error("Action failed", "err", err) "containsOracleData", containsOracleData,
"isLocalPreimage", isLocal,
)
if action.OracleData != nil {
actionLog = actionLog.New("oracleKey", common.Bytes2Hex(action.OracleData.OracleKey))
} }
} else {
actionLog = actionLog.New("value", action.Value)
}
switch action.Type {
case types.ActionTypeMove:
a.metrics.RecordGameMove()
case types.ActionTypeStep:
a.metrics.RecordGameStep()
}
actionLog.Info("Performing action")
err := a.responder.PerformAction(ctx, action)
if err != nil {
actionLog.Error("Action failed", "err", err)
} }
return nil
} }
// tryResolve resolves the game if it is in a winning state // tryResolve resolves the game if it is in a winning state
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment