Commit cbdc8fe5 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-challenger: Use TxSender to batch send resolve claim transactions. (#9933)

Co-authored-by: default avatarrefcell <abigger87@gmail.com>
parent cee53a96
...@@ -23,7 +23,7 @@ type Responder interface { ...@@ -23,7 +23,7 @@ type Responder interface {
CallResolve(ctx context.Context) (gameTypes.GameStatus, error) CallResolve(ctx context.Context) (gameTypes.GameStatus, error)
Resolve() error Resolve() error
CallResolveClaim(ctx context.Context, claimIdx uint64) error CallResolveClaim(ctx context.Context, claimIdx uint64) error
ResolveClaim(claimIdx uint64) error ResolveClaims(claimIdx ...uint64) error
PerformAction(ctx context.Context, action types.Action) error PerformAction(ctx context.Context, action types.Action) error
} }
...@@ -157,7 +157,7 @@ func (a *Agent) tryResolveClaims(ctx context.Context) error { ...@@ -157,7 +157,7 @@ func (a *Agent) tryResolveClaims(ctx context.Context) error {
return errNoResolvableClaims return errNoResolvableClaims
} }
var resolvableClaims []int64 var resolvableClaims []uint64
for _, claim := range claims { for _, claim := range claims {
if a.selective { if a.selective {
a.log.Trace("Selective claim resolution, checking if claim is incentivized", "claimIdx", claim.ContractIndex) a.log.Trace("Selective claim resolution, checking if claim is incentivized", "claimIdx", claim.ContractIndex)
...@@ -171,7 +171,7 @@ func (a *Agent) tryResolveClaims(ctx context.Context) error { ...@@ -171,7 +171,7 @@ func (a *Agent) tryResolveClaims(ctx context.Context) error {
a.log.Trace("Checking if claim is resolvable", "claimIdx", claim.ContractIndex) a.log.Trace("Checking if claim is resolvable", "claimIdx", claim.ContractIndex)
if err := a.responder.CallResolveClaim(ctx, uint64(claim.ContractIndex)); err == nil { if err := a.responder.CallResolveClaim(ctx, uint64(claim.ContractIndex)); err == nil {
a.log.Info("Resolving claim", "claimIdx", claim.ContractIndex) a.log.Info("Resolving claim", "claimIdx", claim.ContractIndex)
resolvableClaims = append(resolvableClaims, int64(claim.ContractIndex)) resolvableClaims = append(resolvableClaims, uint64(claim.ContractIndex))
} }
} }
if len(resolvableClaims) == 0 { if len(resolvableClaims) == 0 {
...@@ -179,19 +179,9 @@ func (a *Agent) tryResolveClaims(ctx context.Context) error { ...@@ -179,19 +179,9 @@ func (a *Agent) tryResolveClaims(ctx context.Context) error {
} }
a.log.Info("Resolving claims", "numClaims", len(resolvableClaims)) a.log.Info("Resolving claims", "numClaims", len(resolvableClaims))
var wg sync.WaitGroup if err := a.responder.ResolveClaims(resolvableClaims...); err != nil {
wg.Add(len(resolvableClaims)) a.log.Error("Failed to resolve claims", "err", err)
for _, claimIdx := range resolvableClaims {
claimIdx := claimIdx
go func() {
defer wg.Done()
err := a.responder.ResolveClaim(uint64(claimIdx))
if err != nil {
a.log.Error("Failed to resolve claim", "err", err)
}
}()
} }
wg.Wait()
return nil return nil
} }
......
...@@ -189,7 +189,7 @@ type stubResponder struct { ...@@ -189,7 +189,7 @@ type stubResponder struct {
resolveClaimCount int resolveClaimCount int
} }
func (s *stubResponder) CallResolve(ctx context.Context) (gameTypes.GameStatus, error) { func (s *stubResponder) CallResolve(_ context.Context) (gameTypes.GameStatus, error) {
s.l.Lock() s.l.Lock()
defer s.l.Unlock() defer s.l.Unlock()
s.callResolveCount++ s.callResolveCount++
...@@ -203,20 +203,20 @@ func (s *stubResponder) Resolve() error { ...@@ -203,20 +203,20 @@ func (s *stubResponder) Resolve() error {
return s.resolveErr return s.resolveErr
} }
func (s *stubResponder) CallResolveClaim(ctx context.Context, clainIdx uint64) error { func (s *stubResponder) CallResolveClaim(_ context.Context, _ uint64) error {
s.l.Lock() s.l.Lock()
defer s.l.Unlock() defer s.l.Unlock()
s.callResolveClaimCount++ s.callResolveClaimCount++
return s.callResolveClaimErr return s.callResolveClaimErr
} }
func (s *stubResponder) ResolveClaim(clainIdx uint64) error { func (s *stubResponder) ResolveClaims(claims ...uint64) error {
s.l.Lock() s.l.Lock()
defer s.l.Unlock() defer s.l.Unlock()
s.resolveClaimCount++ s.resolveClaimCount += len(claims)
return nil return nil
} }
func (s *stubResponder) PerformAction(ctx context.Context, response types.Action) error { func (s *stubResponder) PerformAction(_ context.Context, _ types.Action) error {
return nil return nil
} }
...@@ -76,13 +76,17 @@ func (r *FaultResponder) CallResolveClaim(ctx context.Context, claimIdx uint64) ...@@ -76,13 +76,17 @@ func (r *FaultResponder) CallResolveClaim(ctx context.Context, claimIdx uint64)
return r.contract.CallResolveClaim(ctx, claimIdx) return r.contract.CallResolveClaim(ctx, claimIdx)
} }
// ResolveClaim executes a resolveClaim transaction to resolve a fault dispute game. // ResolveClaims executes resolveClaim transactions to resolve claims in a dispute game.
func (r *FaultResponder) ResolveClaim(claimIdx uint64) error { func (r *FaultResponder) ResolveClaims(claimIdxs ...uint64) error {
txs := make([]txmgr.TxCandidate, 0, len(claimIdxs))
for _, claimIdx := range claimIdxs {
candidate, err := r.contract.ResolveClaimTx(claimIdx) candidate, err := r.contract.ResolveClaimTx(claimIdx)
if err != nil { if err != nil {
return err return err
} }
return r.sender.SendAndWaitSimple("resolve claim", candidate) txs = append(txs, candidate)
}
return r.sender.SendAndWaitSimple("resolve claim", txs...)
} }
func (r *FaultResponder) PerformAction(ctx context.Context, action types.Action) error { func (r *FaultResponder) PerformAction(ctx context.Context, action types.Action) error {
......
...@@ -83,17 +83,24 @@ func TestResolveClaim(t *testing.T) { ...@@ -83,17 +83,24 @@ func TestResolveClaim(t *testing.T) {
t.Run("SendFails", func(t *testing.T) { t.Run("SendFails", func(t *testing.T) {
responder, mockTxMgr, _, _, _ := newTestFaultResponder(t) responder, mockTxMgr, _, _, _ := newTestFaultResponder(t)
mockTxMgr.sendFails = true mockTxMgr.sendFails = true
err := responder.ResolveClaim(0) err := responder.ResolveClaims(0)
require.ErrorIs(t, err, mockSendError) require.ErrorIs(t, err, mockSendError)
require.Equal(t, 0, mockTxMgr.sends) require.Equal(t, 0, mockTxMgr.sends)
}) })
t.Run("Success", func(t *testing.T) { t.Run("Success", func(t *testing.T) {
responder, mockTxMgr, _, _, _ := newTestFaultResponder(t) responder, mockTxMgr, _, _, _ := newTestFaultResponder(t)
err := responder.ResolveClaim(0) err := responder.ResolveClaims(0)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, mockTxMgr.sends) require.Equal(t, 1, mockTxMgr.sends)
}) })
t.Run("Multiple", func(t *testing.T) {
responder, mockTxMgr, _, _, _ := newTestFaultResponder(t)
err := responder.ResolveClaims(0, 1, 2, 3)
require.NoError(t, err)
require.Equal(t, 4, mockTxMgr.sends)
})
} }
// TestRespond tests the [Responder.Respond] method. // TestRespond tests the [Responder.Respond] method.
......
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