-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
user_subscriptions.go
83 lines (68 loc) · 2.68 KB
/
user_subscriptions.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package subscriptions
import (
"math/big"
"reflect"
"github.com/ethereum/go-ethereum/common"
"github.com/pkg/errors"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router"
)
// Methods are NOT thread-safe.
var ErrUserHasNoSubscription = errors.New("user has no subscriptions")
type UserSubscriptions interface {
UpdateSubscription(subscriptionId uint64, subscription *functions_router.IFunctionsSubscriptionsSubscription) bool
GetMaxUserBalance(user common.Address) (*big.Int, error)
}
type userSubscriptions struct {
userSubscriptionsMap map[common.Address]map[uint64]*functions_router.IFunctionsSubscriptionsSubscription
subscriptionIdsMap map[uint64]common.Address
}
func NewUserSubscriptions() UserSubscriptions {
return &userSubscriptions{
userSubscriptionsMap: make(map[common.Address]map[uint64]*functions_router.IFunctionsSubscriptionsSubscription),
subscriptionIdsMap: make(map[uint64]common.Address),
}
}
// StoredSubscription is used to populate the user subscription maps from a persistent layer like postgres.
type StoredSubscription struct {
SubscriptionID uint64
functions_router.IFunctionsSubscriptionsSubscription
}
// UpdateSubscription updates a subscription returning false in case there was no variation to the current state.
func (us *userSubscriptions) UpdateSubscription(subscriptionId uint64, subscription *functions_router.IFunctionsSubscriptionsSubscription) bool {
if subscription == nil || subscription.Owner == utils.ZeroAddress {
user, ok := us.subscriptionIdsMap[subscriptionId]
if !ok {
return false
}
delete(us.userSubscriptionsMap[user], subscriptionId)
delete(us.subscriptionIdsMap, subscriptionId)
if len(us.userSubscriptionsMap[user]) == 0 {
delete(us.userSubscriptionsMap, user)
}
return true
}
// there is no change to the subscription
if reflect.DeepEqual(us.userSubscriptionsMap[subscription.Owner][subscriptionId], subscription) {
return false
}
us.subscriptionIdsMap[subscriptionId] = subscription.Owner
if _, ok := us.userSubscriptionsMap[subscription.Owner]; !ok {
us.userSubscriptionsMap[subscription.Owner] = make(map[uint64]*functions_router.IFunctionsSubscriptionsSubscription)
}
us.userSubscriptionsMap[subscription.Owner][subscriptionId] = subscription
return true
}
func (us *userSubscriptions) GetMaxUserBalance(user common.Address) (*big.Int, error) {
subs, exists := us.userSubscriptionsMap[user]
if !exists {
return nil, ErrUserHasNoSubscription
}
maxBalance := big.NewInt(0)
for _, sub := range subs {
if sub.Balance.Cmp(maxBalance) > 0 {
maxBalance = sub.Balance
}
}
return maxBalance, nil
}