Skip to content

Commit 0a465a4

Browse files
rolled back mutex protection
1 parent ce05327 commit 0a465a4

1 file changed

Lines changed: 54 additions & 55 deletions

File tree

cmd/rpc/sock.go

Lines changed: 54 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,6 @@ type RCManager struct {
5050
subscriberCount int
5151
}
5252

53-
// subSnapshot returns the current subscription pointer and its cached Info pointer (if any)
54-
// under the manager lock. Callers should avoid holding the lock across network calls.
55-
func (r *RCManager) subSnapshot(rootChainId uint64) (sub *RCSubscription, info *lib.RootChainInfo, found bool) {
56-
r.l.Lock()
57-
sub, found = r.subscriptions[rootChainId]
58-
if found && sub != nil {
59-
info = sub.Info
60-
}
61-
r.l.Unlock()
62-
return
63-
}
64-
6553
// NewRCManager() constructs a new instance of a RCManager
6654
func NewRCManager(controller *controller.Controller, config lib.Config, logger lib.LoggerI) (manager *RCManager) {
6755
readLimit := config.RCSubscriberReadLimitBytes
@@ -148,29 +136,43 @@ func (r *RCManager) Publish(chainId uint64, info *lib.RootChainInfo) {
148136

149137
// ChainIds() returns a list of chainIds for subscribers
150138
func (r *RCManager) ChainIds() (list []uint64) {
151-
r.l.Lock()
152-
for chainId, subs := range r.subscribers {
153-
if chainId != 0 && len(subs) != 0 {
154-
list = append(list, chainId)
139+
// de-duplicate the results
140+
deDupe := lib.NewDeDuplicator[uint64]()
141+
// for each client
142+
for chainId, chainSubscribers := range r.subscribers {
143+
// if the client chain id isn't empty and not duplicate
144+
for _, subscriber := range chainSubscribers {
145+
if subscriber.chainId != chainId {
146+
// remove subscriber with incorrect chain id
147+
subscriber.Stop(lib.ErrWrongChainId())
148+
continue
149+
}
150+
if subscriber.chainId != 0 && !deDupe.Found(subscriber.chainId) {
151+
list = append(list, subscriber.chainId)
152+
}
155153
}
156154
}
157-
r.l.Unlock()
158-
return list
155+
return
159156
}
160157

161158
// GetHeight() returns the height from the root-chain
162159
func (r *RCManager) GetHeight(rootChainId uint64) uint64 {
163-
_, info, found := r.subSnapshot(rootChainId)
164-
if found && info != nil {
165-
return info.Height
160+
// check the map to see if the info exists
161+
if sub, found := r.subscriptions[rootChainId]; found {
162+
// exit with the height of the root-chain-info
163+
return sub.Info.Height
166164
}
167165
return 0
168166
}
169167

170168
// GetRootChainInfo() retrieves the root chain info from the root chain 'on-demand'
171169
func (r *RCManager) GetRootChainInfo(rootChainId, chainId uint64) (info *lib.RootChainInfo, err lib.ErrorI) {
172170
defer lib.TimeTrack(r.log, time.Now(), 500*time.Millisecond)
173-
sub, _, found := r.subSnapshot(rootChainId)
171+
// lock for thread safety
172+
r.l.Lock()
173+
defer r.l.Unlock()
174+
// if the root chain id is the same as the info
175+
sub, found := r.subscriptions[rootChainId]
174176
if !found {
175177
// exit with 'not subscribed' error
176178
return nil, lib.ErrNotSubscribed()
@@ -180,63 +182,53 @@ func (r *RCManager) GetRootChainInfo(rootChainId, chainId uint64) (info *lib.Roo
180182
if err != nil {
181183
return nil, err
182184
}
183-
// update cached info under lock (don't hold the lock during the RPC call above)
184-
r.l.Lock()
185-
if cur, ok := r.subscriptions[rootChainId]; ok && cur == sub {
186-
sub.Info = info
187-
}
188-
r.l.Unlock()
185+
// update the info
186+
sub.Info = info
189187
// exit with the info
190188
return
191189
}
192190

193191
// GetValidatorSet() returns the validator set from the root-chain
194192
func (r *RCManager) GetValidatorSet(rootChainId, id, rootHeight uint64) (lib.ValidatorSet, lib.ErrorI) {
195193
defer lib.TimeTrack(r.log, time.Now(), 500*time.Millisecond)
196-
sub, info, found := r.subSnapshot(rootChainId)
194+
// if the root chain id is the same as the info
195+
sub, found := r.subscriptions[rootChainId]
197196
if !found {
198197
// exit with 'not subscribed' error
199198
return lib.ValidatorSet{}, lib.ErrNotSubscribed()
200199
}
201200
// if rootHeight is the same as the RootChainInfo height
202-
if info != nil && (rootHeight == info.Height || rootHeight == 0) {
201+
if rootHeight == sub.Info.Height || rootHeight == 0 {
203202
// exit with a copy the validator set
204-
return lib.NewValidatorSet(info.ValidatorSet)
203+
return lib.NewValidatorSet(sub.Info.ValidatorSet)
205204
}
206205
// if rootHeight is 1 before the RootChainInfo height
207-
if info != nil && info.Height != 0 && rootHeight == info.Height-1 {
206+
if rootHeight == sub.Info.Height-1 {
208207
// exit with a copy of the previous validator set
209-
return lib.NewValidatorSet(info.LastValidatorSet)
208+
return lib.NewValidatorSet(sub.Info.LastValidatorSet)
210209
}
211210
// warn of the remote RPC call to the root chain API
212-
latest := uint64(0)
213-
if info != nil {
214-
latest = info.Height
215-
}
216-
r.log.Warnf("Executing remote GetValidatorSet call with requested height=%d for rootChainId=%d with latest root height at %d", rootHeight, rootChainId, latest)
211+
r.log.Warnf("Executing remote GetValidatorSet call with requested height=%d for rootChainId=%d with latest root height at %d", rootHeight, rootChainId, sub.Info.Height)
217212
// execute the remote RPC call to the root chain API
218213
return sub.ValidatorSet(rootHeight, id)
219214
}
220215

221216
// GetOrders() returns the order book from the root-chain
222217
func (r *RCManager) GetOrders(rootChainId, rootHeight, id uint64) (*lib.OrderBook, lib.ErrorI) {
223218
defer lib.TimeTrack(r.log, time.Now(), 500*time.Millisecond)
224-
sub, info, found := r.subSnapshot(rootChainId)
219+
// if the root chain id is the same as the info
220+
sub, found := r.subscriptions[rootChainId]
225221
if !found {
226222
// exit with 'not subscribed' error
227223
return nil, lib.ErrNotSubscribed()
228224
}
229225
// if the root chain id and height is the same as the info
230-
if info != nil && info.Height == rootHeight {
226+
if sub.Info.Height == rootHeight {
231227
// exit with the order books from memory
232-
return info.Orders, nil
228+
return sub.Info.Orders, nil
233229
}
234230
// warn of the remote RPC call to the root chain API
235-
latest := uint64(0)
236-
if info != nil {
237-
latest = info.Height
238-
}
239-
r.log.Warnf("Executing remote GetOrders call with requested height=%d for rootChainId=%d with latest root height at %d", rootHeight, rootChainId, latest)
231+
r.log.Warnf("Executing remote GetOrders call with requested height=%d for rootChainId=%d with latest root height at %d", rootHeight, rootChainId, sub.Info.Height)
240232
// execute the remote call
241233
books, err := sub.Orders(rootHeight, id)
242234
// if an error occurred during the remote call
@@ -256,7 +248,8 @@ func (r *RCManager) GetOrders(rootChainId, rootHeight, id uint64) (*lib.OrderBoo
256248
// Order() returns a specific order from the root order book
257249
func (r *RCManager) GetOrder(rootChainId, height uint64, orderId string, chainId uint64) (*lib.SellOrder, lib.ErrorI) {
258250
defer lib.TimeTrack(r.log, time.Now(), 500*time.Millisecond)
259-
sub, _, found := r.subSnapshot(rootChainId)
251+
// if the root chain id is the same as the info
252+
sub, found := r.subscriptions[rootChainId]
260253
if !found {
261254
// exit with 'not subscribed' error
262255
return nil, lib.ErrNotSubscribed()
@@ -267,7 +260,8 @@ func (r *RCManager) GetOrder(rootChainId, height uint64, orderId string, chainId
267260
// IsValidDoubleSigner() returns if an address is a valid double signer for a specific 'double sign height'
268261
func (r *RCManager) IsValidDoubleSigner(rootChainId, height uint64, address string) (*bool, lib.ErrorI) {
269262
defer lib.TimeTrack(r.log, time.Now(), 500*time.Millisecond)
270-
sub, _, found := r.subSnapshot(rootChainId)
263+
// if the root chain id is the same as the info
264+
sub, found := r.subscriptions[rootChainId]
271265
if !found {
272266
// exit with 'not subscribed' error
273267
return nil, lib.ErrNotSubscribed()
@@ -279,7 +273,8 @@ func (r *RCManager) IsValidDoubleSigner(rootChainId, height uint64, address stri
279273
// GetMinimumEvidenceHeight() returns the minimum height double sign evidence must have to be 'valid'
280274
func (r *RCManager) GetMinimumEvidenceHeight(rootChainId, height uint64) (*uint64, lib.ErrorI) {
281275
defer lib.TimeTrack(r.log, time.Now(), 500*time.Millisecond)
282-
sub, _, found := r.subSnapshot(rootChainId)
276+
// if the root chain id is the same as the info
277+
sub, found := r.subscriptions[rootChainId]
283278
if !found {
284279
// exit with 'not subscribed' error
285280
return nil, lib.ErrNotSubscribed()
@@ -292,7 +287,8 @@ func (r *RCManager) GetMinimumEvidenceHeight(rootChainId, height uint64) (*uint6
292287
// TODO should be able to get these from the file or the root-chain upon independence
293288
func (r *RCManager) GetCheckpoint(rootChainId, height, chainId uint64) (blockHash lib.HexBytes, err lib.ErrorI) {
294289
defer lib.TimeTrack(r.log, time.Now(), 500*time.Millisecond)
295-
sub, _, found := r.subSnapshot(rootChainId)
290+
// if the root chain id is the same as the info
291+
sub, found := r.subscriptions[rootChainId]
296292
if !found {
297293
// exit with 'not subscribed' error
298294
return nil, lib.ErrNotSubscribed()
@@ -304,15 +300,16 @@ func (r *RCManager) GetCheckpoint(rootChainId, height, chainId uint64) (blockHas
304300
// GetLotteryWinner() returns the winner of the delegate lottery from the root-chain
305301
func (r *RCManager) GetLotteryWinner(rootChainId, height, id uint64) (*lib.LotteryWinner, lib.ErrorI) {
306302
defer lib.TimeTrack(r.log, time.Now(), 500*time.Millisecond)
307-
sub, info, found := r.subSnapshot(rootChainId)
303+
// if the root chain id is the same as the info
304+
sub, found := r.subscriptions[rootChainId]
308305
if !found {
309306
// exit with 'not subscribed' error
310307
return nil, lib.ErrNotSubscribed()
311308
}
312309
// if the root chain id and height is the same as the info
313-
if info != nil && info.Height == height {
310+
if sub.Info.Height == height {
314311
// exit with the lottery winner
315-
return info.LotteryWinner, nil
312+
return sub.Info.LotteryWinner, nil
316313
}
317314
// exit with the results of the remote RPC call to the API of the 'root chain'
318315
return sub.Lottery(height, id)
@@ -321,7 +318,8 @@ func (r *RCManager) GetLotteryWinner(rootChainId, height, id uint64) (*lib.Lotte
321318
// Transaction() executes a transaction on the root chain
322319
func (r *RCManager) Transaction(rootChainId uint64, tx lib.TransactionI) (hash *string, err lib.ErrorI) {
323320
defer lib.TimeTrack(r.log, time.Now(), 500*time.Millisecond)
324-
sub, _, found := r.subSnapshot(rootChainId)
321+
// if the root chain id is the same as the info
322+
sub, found := r.subscriptions[rootChainId]
325323
if !found {
326324
// exit with 'not subscribed' error
327325
return nil, lib.ErrNotSubscribed()
@@ -332,7 +330,8 @@ func (r *RCManager) Transaction(rootChainId uint64, tx lib.TransactionI) (hash *
332330
// GetDexBatch() queries a 'dex batch on the root chain
333331
func (r *RCManager) GetDexBatch(rootChainId, height, committee uint64, withPoints bool) (*lib.DexBatch, lib.ErrorI) {
334332
defer lib.TimeTrack(r.log, time.Now(), 500*time.Millisecond)
335-
sub, _, found := r.subSnapshot(rootChainId)
333+
// if the root chain id is the same as the info
334+
sub, found := r.subscriptions[rootChainId]
336335
if !found {
337336
// exit with 'not subscribed' error
338337
return nil, lib.ErrNotSubscribed()

0 commit comments

Comments
 (0)