@@ -33,33 +33,25 @@ const secondaryWaitBlocks = 2
3333// ensureConcluded ensures that conclude or concludeFinal (for non-final and
3434// final states, resp.) is called on the adjudicator.
3535// - a subscription on Concluded events is established
36- // - it searches for a past concluded event
36+ // - it searches for a past concluded event by calling `isConcluded`
3737// - if found, channel is already concluded and success is returned
3838// - if none found, conclude/concludeFinal is called on the adjudicator
3939// - it waits for a Concluded event from the blockchain.
40- // nolint: funlen
4140func (a * Adjudicator ) ensureConcluded (ctx context.Context , req channel.AdjudicatorReq , subStates channel.StateMap ) error {
42- // Listen for Concluded event.
43- events := make (chan * subscription.Event , 10 )
44- subErr := make (chan error , 1 )
4541 sub , err := subscription .NewEventSub (ctx , a .ContractBackend , a .bound , updateEventType (req .Params .ID ()), startBlockOffset )
4642 if err != nil {
4743 return errors .WithMessage (err , "subscribing" )
4844 }
4945 defer sub .Close ()
50- // Check for past event
51- if err := sub .ReadPast (ctx , events ); err != nil {
52- return errors .WithMessage (err , "reading past events" )
53- }
54- select {
55- case _e := <- events :
56- e := _e .Data .(* adjudicator.AdjudicatorChannelUpdate )
57- if e .Phase == phaseConcluded {
58- return nil
59- }
60- default :
46+ // Check whether it is already concluded.
47+ if concluded , err := a .isConcluded (ctx , sub ); err != nil {
48+ return errors .WithMessage (err , "isConcluded" )
49+ } else if concluded {
50+ return nil
6151 }
6252
53+ events := make (chan * subscription.Event , 10 )
54+ subErr := make (chan error , 1 )
6355 waitCtx , cancel := context .WithCancel (ctx )
6456 go func () {
6557 subErr <- sub .Read (ctx , events )
@@ -108,6 +100,25 @@ func (a *Adjudicator) ensureConcluded(ctx context.Context, req channel.Adjudicat
108100 }
109101}
110102
103+ // isConcluded returns whether a channel is already concluded.
104+ func (a * Adjudicator ) isConcluded (ctx context.Context , sub * subscription.EventSub ) (bool , error ) {
105+ events := make (chan * subscription.Event , 10 )
106+ subErr := make (chan error , 1 )
107+ // Write the events into events.
108+ go func () {
109+ defer close (events )
110+ subErr <- sub .ReadPast (ctx , events )
111+ }()
112+ // Read all events and check for concluded.
113+ for _e := range events {
114+ e := _e .Data .(* adjudicator.AdjudicatorChannelUpdate )
115+ if e .Phase == phaseConcluded {
116+ return true , nil
117+ }
118+ }
119+ return false , errors .WithMessage (<- subErr , "reading past events" )
120+ }
121+
111122func updateEventType (channelID [32 ]byte ) subscription.EventFactory {
112123 return func () * subscription.Event {
113124 return & subscription.Event {
0 commit comments