@@ -2,56 +2,67 @@ package registrar
2
2
3
3
import (
4
4
"context"
5
+ "fmt"
5
6
"os"
7
+ "reflect"
6
8
"sync"
7
9
"time"
8
10
9
11
"github.com/cenkalti/backoff/v3"
10
12
"github.com/pkg/errors"
11
13
"github.com/rs/zerolog/log"
14
+ substrate "github.com/threefoldtech/tfchain/clients/tfchain-client-go"
12
15
"github.com/threefoldtech/zbus"
13
- "github.com/threefoldtech/zos/pkg"
14
16
"github.com/threefoldtech/zos/pkg/app"
15
17
"github.com/threefoldtech/zos/pkg/environment"
18
+ "github.com/threefoldtech/zos/pkg/geoip"
16
19
"github.com/threefoldtech/zos/pkg/stubs"
17
20
)
18
21
19
22
// should any of this be moved to pkg?
23
+ type RegistrationState string
20
24
21
25
const (
22
- Failed pkg. RegistrationState = "Failed"
23
- InProgress pkg. RegistrationState = "InProgress"
24
- Done pkg. RegistrationState = "Done"
26
+ Failed RegistrationState = "Failed"
27
+ InProgress RegistrationState = "InProgress"
28
+ Done RegistrationState = "Done"
25
29
26
30
monitorAccountEvery = 30 * time .Minute
27
- updateNodeInfoInterval = 24 * time .Hour
31
+ updateLocationInterval = 24 * time .Hour
28
32
)
29
33
30
34
var (
31
35
ErrInProgress = errors .New ("registration is still in progress" )
32
36
ErrFailed = errors .New ("registration failed" )
33
37
)
34
38
35
- func FailedState (err error ) pkg.State {
36
- return pkg.State {
39
+ type State struct {
40
+ NodeID uint32
41
+ TwinID uint32
42
+ State RegistrationState
43
+ Msg string
44
+ }
45
+
46
+ func FailedState (err error ) State {
47
+ return State {
37
48
0 ,
38
49
0 ,
39
50
Failed ,
40
51
err .Error (),
41
52
}
42
53
}
43
54
44
- func InProgressState () pkg. State {
45
- return pkg. State {
55
+ func InProgressState () State {
56
+ return State {
46
57
0 ,
47
58
0 ,
48
59
InProgress ,
49
60
"" ,
50
61
}
51
62
}
52
63
53
- func DoneState (nodeID uint32 , twinID uint32 ) pkg. State {
54
- return pkg. State {
64
+ func DoneState (nodeID uint32 , twinID uint32 ) State {
65
+ return State {
55
66
nodeID ,
56
67
twinID ,
57
68
Done ,
@@ -60,32 +71,32 @@ func DoneState(nodeID uint32, twinID uint32) pkg.State {
60
71
}
61
72
62
73
type Registrar struct {
63
- state pkg. State
74
+ state State
64
75
mutex sync.RWMutex
65
76
}
66
77
67
78
func NewRegistrar (ctx context.Context , cl zbus.Client , env environment.Environment , info RegistrationInfo ) * Registrar {
68
79
r := Registrar {
69
- pkg. State {
80
+ state : State {
70
81
0 ,
71
82
0 ,
72
83
InProgress ,
73
84
"" ,
74
85
},
75
- sync.RWMutex {},
86
+ mutex : sync.RWMutex {},
76
87
}
77
88
78
89
go r .register (ctx , cl , env , info )
79
90
return & r
80
91
}
81
92
82
- func (r * Registrar ) setState (s pkg. State ) {
93
+ func (r * Registrar ) setState (s State ) {
83
94
r .mutex .Lock ()
84
95
defer r .mutex .Unlock ()
85
96
r .state = s
86
97
}
87
98
88
- func (r * Registrar ) GetState () pkg. State {
99
+ func (r * Registrar ) getState () State {
89
100
r .mutex .RLock ()
90
101
defer r .mutex .RUnlock ()
91
102
return r .state
@@ -141,9 +152,16 @@ func (r *Registrar) register(ctx context.Context, cl zbus.Client, env environmen
141
152
if err := r .reActivate (ctx , cl , env ); err != nil {
142
153
log .Error ().Err (err ).Msg ("failed to reactivate account" )
143
154
}
155
+ << << << < HEAD
144
156
case <- time .After (updateNodeInfoInterval ):
145
157
log .Info ().Msg ("update interval passed, re-register" )
146
158
register ()
159
+ == == == =
160
+ case <- time .After (updateLocationInterval ):
161
+ if err := r .updateLocation (ctx , cl ); err != nil {
162
+ log .Error ().Err (err ).Msg ("updating location failed" )
163
+ }
164
+ >> >> >> > 3 b559b8b (move the location update to the register pkg )
147
165
case <- addressesUpdate :
148
166
log .Info ().Msg ("zos address has changed, re-register" )
149
167
register ()
@@ -159,12 +177,52 @@ func (r *Registrar) reActivate(ctx context.Context, cl zbus.Client, env environm
159
177
return err
160
178
}
161
179
180
+ // updateLocation validates the node location on chain against the geoip
181
+ // service and update it if needed.
182
+ func (r * Registrar ) updateLocation (ctx context.Context , cl zbus.Client ) error {
183
+ nodeId , err := r .NodeID ()
184
+ if err != nil {
185
+ return fmt .Errorf ("failed to get node id: %w" , err )
186
+ }
187
+
188
+ substrateGw := stubs .NewSubstrateGatewayStub (cl )
189
+ node , err := substrateGw .GetNode (ctx , nodeId )
190
+ if err != nil {
191
+ return fmt .Errorf ("failed to get node from chain: %w" , err )
192
+ }
193
+
194
+ loc , err := geoip .Fetch ()
195
+ if err != nil {
196
+ return fmt .Errorf ("failed to fetch location info: %w" , err )
197
+ }
198
+
199
+ newLoc := substrate.Location {
200
+ City : loc .City ,
201
+ Country : loc .Country ,
202
+ Latitude : fmt .Sprintf ("%f" , loc .Latitude ),
203
+ Longitude : fmt .Sprintf ("%f" , loc .Longitude ),
204
+ }
205
+
206
+ if reflect .DeepEqual (newLoc , node .Location ) {
207
+ // no need to update
208
+ return nil
209
+ }
210
+
211
+ node .Location = newLoc
212
+ if _ , err := substrateGw .UpdateNode (ctx , node ); err != nil {
213
+ return fmt .Errorf ("failed to update node on chain: %w" , err )
214
+ }
215
+
216
+ log .Info ().Msg ("node location updated" )
217
+ return nil
218
+ }
219
+
162
220
func (r * Registrar ) NodeID () (uint32 , error ) {
163
- return r .returnIfDone (r .GetState ().NodeID )
221
+ return r .returnIfDone (r .getState ().NodeID )
164
222
}
165
223
166
224
func (r * Registrar ) TwinID () (uint32 , error ) {
167
- return r .returnIfDone (r .GetState ().TwinID )
225
+ return r .returnIfDone (r .getState ().TwinID )
168
226
}
169
227
170
228
func (r * Registrar ) returnIfDone (v uint32 ) (uint32 , error ) {
0 commit comments