@@ -88,29 +88,38 @@ func (s *ShutterStateSyncer) Start(ctx context.Context, runner service.Runner) e
88
88
if s .Handler == nil {
89
89
return errors .New ("no handler registered" )
90
90
}
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 (),
93
104
Context : ctx ,
94
105
}
95
106
s .pausedCh = make (chan * bindings.KeyperSetManagerPaused )
96
107
runner .Defer (func () {
97
108
close (s .pausedCh )
98
109
})
99
110
s .unpausedCh = make (chan * bindings.KeyperSetManagerUnpaused )
100
- if ! s .DisableEventWatcher {
101
- }
102
111
runner .Defer (func () {
103
112
close (s .unpausedCh )
104
113
})
105
114
106
115
if ! s .DisableEventWatcher {
107
- subs , err := s .Contract .WatchPaused (watchOpts , s .pausedCh )
116
+ subs , err := s .Contract .WatchPaused (opts , s .pausedCh )
108
117
// FIXME: what to do on subs.Error()
109
118
if err != nil {
110
119
return err
111
120
}
112
121
runner .Defer (subs .Unsubscribe )
113
- subs , err = s .Contract .WatchUnpaused (watchOpts , s .unpausedCh )
122
+ subs , err = s .Contract .WatchUnpaused (opts , s .unpausedCh )
114
123
// FIXME: what to do on subs.Error()
115
124
if err != nil {
116
125
return err
@@ -124,14 +133,6 @@ func (s *ShutterStateSyncer) Start(ctx context.Context, runner service.Runner) e
124
133
return nil
125
134
}
126
135
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
-
135
136
func (s * ShutterStateSyncer ) handle (ctx context.Context , ev * event.ShutterState ) {
136
137
err := s .Handler (ctx , ev )
137
138
if err != nil {
@@ -144,40 +145,56 @@ func (s *ShutterStateSyncer) handle(ctx context.Context, ev *event.ShutterState)
144
145
}
145
146
146
147
func (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 )
148
157
if err != nil {
149
158
// XXX: this will fail everything, do we want that?
150
159
return err
151
160
}
152
- ev := & event.ShutterState {
153
- Active : isActive ,
154
- }
155
- s .handle (ctx , ev )
161
+ s .handle (ctx , stateAtStartBlock )
162
+ lastState := stateAtStartBlock
156
163
for {
157
164
select {
158
- case _ , ok := <- s .unpausedCh :
165
+ case unpaused , ok := <- s .unpausedCh :
159
166
if ! ok {
160
167
return nil
161
168
}
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
+ )
164
175
}
176
+ block := unpaused .Raw .BlockNumber
165
177
ev := & event.ShutterState {
166
- Active : true ,
178
+ Active : true ,
179
+ AtBlockNumber : number .NewBlockNumber (& block ),
167
180
}
168
- isActive = ev .Active
169
181
s .handle (ctx , ev )
170
- case _ , ok := <- s .pausedCh :
182
+ case paused , ok := <- s .pausedCh :
171
183
if ! ok {
172
184
return nil
173
185
}
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
+ )
176
192
}
193
+ block := paused .Raw .BlockNumber
177
194
ev := & event.ShutterState {
178
- Active : false ,
195
+ Active : false ,
196
+ AtBlockNumber : number .NewBlockNumber (& block ),
179
197
}
180
- isActive = ev .Active
181
198
s .handle (ctx , ev )
182
199
case <- ctx .Done ():
183
200
return ctx .Err ()
0 commit comments