@@ -88,29 +88,38 @@ func (s *ShutterStateSyncer) Start(ctx context.Context, runner service.Runner) e
8888 if s .Handler == nil {
8989 return errors .New ("no handler registered" )
9090 }
91- watchOpts := & bind.WatchOpts {
92- Start : s .StartBlock .ToUInt64Ptr (), // nil means latest
91+ // the latest block still has to be fixed.
92+ // otherwise we could skip some block events
93+ // between the initial poll and the subscription.
94+ if s .StartBlock .IsLatest () {
95+ latest , err := s .Client .BlockNumber (ctx )
96+ if err != nil {
97+ return err
98+ }
99+ s .StartBlock .SetUint64 (latest )
100+ }
101+
102+ opts := & bind.WatchOpts {
103+ Start : s .StartBlock .ToUInt64Ptr (),
93104 Context : ctx ,
94105 }
95106 s .pausedCh = make (chan * bindings.KeyperSetManagerPaused )
96107 runner .Defer (func () {
97108 close (s .pausedCh )
98109 })
99110 s .unpausedCh = make (chan * bindings.KeyperSetManagerUnpaused )
100- if ! s .DisableEventWatcher {
101- }
102111 runner .Defer (func () {
103112 close (s .unpausedCh )
104113 })
105114
106115 if ! s .DisableEventWatcher {
107- subs , err := s .Contract .WatchPaused (watchOpts , s .pausedCh )
116+ subs , err := s .Contract .WatchPaused (opts , s .pausedCh )
108117 // FIXME: what to do on subs.Error()
109118 if err != nil {
110119 return err
111120 }
112121 runner .Defer (subs .Unsubscribe )
113- subs , err = s .Contract .WatchUnpaused (watchOpts , s .unpausedCh )
122+ subs , err = s .Contract .WatchUnpaused (opts , s .unpausedCh )
114123 // FIXME: what to do on subs.Error()
115124 if err != nil {
116125 return err
@@ -124,14 +133,6 @@ func (s *ShutterStateSyncer) Start(ctx context.Context, runner service.Runner) e
124133 return nil
125134}
126135
127- func (s * ShutterStateSyncer ) pollIsActive (ctx context.Context ) (bool , error ) {
128- callOpts := bind.CallOpts {
129- Context : ctx ,
130- }
131- paused , err := s .Contract .Paused (& callOpts )
132- return ! paused , err
133- }
134-
135136func (s * ShutterStateSyncer ) handle (ctx context.Context , ev * event.ShutterState ) {
136137 err := s .Handler (ctx , ev )
137138 if err != nil {
@@ -144,40 +145,56 @@ func (s *ShutterStateSyncer) handle(ctx context.Context, ev *event.ShutterState)
144145}
145146
146147func (s * ShutterStateSyncer ) watchPaused (ctx context.Context ) error {
147- isActive , err := s .pollIsActive (ctx )
148+ // query the initial state
149+ // and construct a "virtual"
150+ // event
151+ opts := & bind.CallOpts {
152+ BlockNumber : s .StartBlock .Int ,
153+ Context : nil ,
154+ }
155+
156+ stateAtStartBlock , err := s .GetShutterState (ctx , opts )
148157 if err != nil {
149158 // XXX: this will fail everything, do we want that?
150159 return err
151160 }
152- ev := & event.ShutterState {
153- Active : isActive ,
154- }
155- s .handle (ctx , ev )
161+ s .handle (ctx , stateAtStartBlock )
162+ lastState := stateAtStartBlock
156163 for {
157164 select {
158- case _ , ok := <- s .unpausedCh :
165+ case unpaused , ok := <- s .unpausedCh :
159166 if ! ok {
160167 return nil
161168 }
162- if isActive {
163- s .Log .Error ("state mismatch" , "got" , "actice" , "have" , "inactive" )
169+ if lastState .Active {
170+ s .Log .Warn (
171+ "state/event mismatch, but continue handler" ,
172+ "new-event" , "Unpaused" ,
173+ "last-state" , "active" ,
174+ )
164175 }
176+ block := unpaused .Raw .BlockNumber
165177 ev := & event.ShutterState {
166- Active : true ,
178+ Active : true ,
179+ AtBlockNumber : number .NewBlockNumber (& block ),
167180 }
168- isActive = ev .Active
169181 s .handle (ctx , ev )
170- case _ , ok := <- s .pausedCh :
182+ case paused , ok := <- s .pausedCh :
171183 if ! ok {
172184 return nil
173185 }
174- if isActive {
175- s .Log .Error ("state mismatch" , "got" , "inactive" , "have" , "active" )
186+ if ! lastState .Active {
187+ s .Log .Warn (
188+ "state/event mismatch, but continue handler" ,
189+ "new-event" , "Paused" ,
190+ "last-state" , "inactive" ,
191+ )
176192 }
193+ block := paused .Raw .BlockNumber
177194 ev := & event.ShutterState {
178- Active : false ,
195+ Active : false ,
196+ AtBlockNumber : number .NewBlockNumber (& block ),
179197 }
180- isActive = ev .Active
181198 s .handle (ctx , ev )
182199 case <- ctx .Done ():
183200 return ctx .Err ()
0 commit comments