mirror of
https://github.com/status-im/status-go.git
synced 2025-02-20 10:48:36 +00:00
refactor: extract messenger_curated_communities.go
This commit is contained in:
parent
cd03dd949e
commit
5b51c32a4a
@ -5,7 +5,6 @@ import (
|
|||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -21,8 +20,6 @@ import (
|
|||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
||||||
|
|
||||||
"github.com/status-im/status-go/account"
|
"github.com/status-im/status-go/account"
|
||||||
"github.com/status-im/status-go/eth-node/crypto"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
@ -557,165 +554,6 @@ func (m *Messenger) SpectatedCommunities() ([]*communities.Community, error) {
|
|||||||
return m.communitiesManager.Spectated()
|
return m.communitiesManager.Spectated()
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
fetchError int = 0
|
|
||||||
fetchSuccess int = 1
|
|
||||||
fetchHasUnknowns int = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
func calcTimeTillNextUpdate(fetchResultsHistory []int) time.Duration {
|
|
||||||
// TODO lower this back again once the real curated community contract is up
|
|
||||||
// The current contract contains communities that are no longer accessible on waku
|
|
||||||
const shortTimeout = 30 * time.Second
|
|
||||||
const averageTimeout = 60 * time.Second
|
|
||||||
const longTimeout = 300 * time.Second
|
|
||||||
|
|
||||||
twoConsecutiveErrors := (len(fetchResultsHistory) == 2 &&
|
|
||||||
fetchResultsHistory[0] == fetchError &&
|
|
||||||
fetchResultsHistory[1] == fetchError)
|
|
||||||
|
|
||||||
twoConsecutiveHasUnknowns := (len(fetchResultsHistory) == 2 &&
|
|
||||||
fetchResultsHistory[0] == fetchHasUnknowns &&
|
|
||||||
fetchResultsHistory[1] == fetchHasUnknowns)
|
|
||||||
|
|
||||||
var timeTillNextUpdate time.Duration
|
|
||||||
|
|
||||||
if twoConsecutiveErrors || twoConsecutiveHasUnknowns {
|
|
||||||
timeTillNextUpdate = longTimeout
|
|
||||||
} else {
|
|
||||||
switch fetchResultsHistory[len(fetchResultsHistory)-1] {
|
|
||||||
case fetchError:
|
|
||||||
timeTillNextUpdate = shortTimeout
|
|
||||||
case fetchSuccess:
|
|
||||||
timeTillNextUpdate = longTimeout
|
|
||||||
case fetchHasUnknowns:
|
|
||||||
timeTillNextUpdate = averageTimeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return timeTillNextUpdate
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regularly gets list of curated communities and signals them to client
|
|
||||||
func (m *Messenger) startCuratedCommunitiesUpdateLoop() {
|
|
||||||
logger := m.logger.Named("startCuratedCommunitiesUpdateLoop")
|
|
||||||
|
|
||||||
type curatedCommunities struct {
|
|
||||||
ContractCommunities []string
|
|
||||||
ContractFeaturedCommunities []string
|
|
||||||
UnknownCommunities []string
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
|
|
||||||
var fetchResultsHistory = make([]int, 0)
|
|
||||||
var mu = sync.RWMutex{}
|
|
||||||
var c = curatedCommunities{}
|
|
||||||
|
|
||||||
for {
|
|
||||||
response, err := m.CuratedCommunities()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fetchResultsHistory = append(fetchResultsHistory, fetchError)
|
|
||||||
} else {
|
|
||||||
mu.Lock()
|
|
||||||
// Check if it's the same values we had
|
|
||||||
if !reflect.DeepEqual(c.ContractCommunities, response.ContractCommunities) ||
|
|
||||||
!reflect.DeepEqual(c.ContractFeaturedCommunities, response.ContractFeaturedCommunities) ||
|
|
||||||
!reflect.DeepEqual(c.UnknownCommunities, response.UnknownCommunities) {
|
|
||||||
// One of the communities is different, send the updated response
|
|
||||||
m.config.messengerSignalsHandler.SendCuratedCommunitiesUpdate(response)
|
|
||||||
|
|
||||||
// Update the values
|
|
||||||
c.ContractCommunities = response.ContractCommunities
|
|
||||||
c.ContractFeaturedCommunities = response.ContractFeaturedCommunities
|
|
||||||
c.UnknownCommunities = response.UnknownCommunities
|
|
||||||
}
|
|
||||||
mu.Unlock()
|
|
||||||
|
|
||||||
if len(response.UnknownCommunities) == 0 {
|
|
||||||
fetchResultsHistory = append(fetchResultsHistory, fetchSuccess)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
fetchResultsHistory = append(fetchResultsHistory, fetchHasUnknowns)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//keep only 2 last fetch results
|
|
||||||
if len(fetchResultsHistory) > 2 {
|
|
||||||
fetchResultsHistory = fetchResultsHistory[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
timeTillNextUpdate := calcTimeTillNextUpdate(fetchResultsHistory)
|
|
||||||
logger.Debug("Next curated communities update will happen in", zap.Duration("timeTillNextUpdate", timeTillNextUpdate))
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-time.After(timeTillNextUpdate):
|
|
||||||
case <-m.quit:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Messenger) CuratedCommunities() (*communities.KnownCommunitiesResponse, error) {
|
|
||||||
if m.contractMaker == nil {
|
|
||||||
m.logger.Warn("contract maker not initialized")
|
|
||||||
return nil, errors.New("contract maker not initialized")
|
|
||||||
}
|
|
||||||
|
|
||||||
testNetworksEnabled, err := m.settings.GetTestNetworksEnabled()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
chainID := uint64(10) // Optimism Mainnet
|
|
||||||
if testNetworksEnabled {
|
|
||||||
chainID = 420 // Optimism Goerli
|
|
||||||
}
|
|
||||||
|
|
||||||
directory, err := m.contractMaker.NewDirectory(chainID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
callOpts := &bind.CallOpts{Context: context.Background(), Pending: false}
|
|
||||||
|
|
||||||
curatedCommunities, err := directory.GetCommunities(callOpts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var communityIDs []types.HexBytes
|
|
||||||
for _, c := range curatedCommunities {
|
|
||||||
communityIDs = append(communityIDs, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
response, err := m.communitiesManager.GetStoredDescriptionForCommunities(communityIDs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
featuredCommunities, err := directory.GetFeaturedCommunities(callOpts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range featuredCommunities {
|
|
||||||
response.ContractFeaturedCommunities = append(response.ContractFeaturedCommunities, types.HexBytes(c).String())
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: use mechanism to obtain shard from community ID (https://github.com/status-im/status-desktop/issues/12585)
|
|
||||||
var unknownCommunities []communities.CommunityShard
|
|
||||||
for _, u := range response.UnknownCommunities {
|
|
||||||
unknownCommunities = append(unknownCommunities, communities.CommunityShard{
|
|
||||||
CommunityID: u,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
go m.requestCommunitiesFromMailserver(unknownCommunities)
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Messenger) initCommunityChats(community *communities.Community) ([]*Chat, error) {
|
func (m *Messenger) initCommunityChats(community *communities.Community) ([]*Chat, error) {
|
||||||
logger := m.logger.Named("initCommunityChats")
|
logger := m.logger.Named("initCommunityChats")
|
||||||
|
|
||||||
|
174
protocol/messenger_curated_communities.go
Normal file
174
protocol/messenger_curated_communities.go
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
"github.com/status-im/status-go/protocol/communities"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
fetchError int = 0
|
||||||
|
fetchSuccess int = 1
|
||||||
|
fetchHasUnknowns int = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Regularly gets list of curated communities and signals them to client
|
||||||
|
func (m *Messenger) startCuratedCommunitiesUpdateLoop() {
|
||||||
|
logger := m.logger.Named("startCuratedCommunitiesUpdateLoop")
|
||||||
|
|
||||||
|
type curatedCommunities struct {
|
||||||
|
ContractCommunities []string
|
||||||
|
ContractFeaturedCommunities []string
|
||||||
|
UnknownCommunities []string
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
|
||||||
|
var fetchResultsHistory = make([]int, 0)
|
||||||
|
var mu = sync.RWMutex{}
|
||||||
|
var c = curatedCommunities{}
|
||||||
|
|
||||||
|
for {
|
||||||
|
response, err := m.CuratedCommunities()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fetchResultsHistory = append(fetchResultsHistory, fetchError)
|
||||||
|
} else {
|
||||||
|
mu.Lock()
|
||||||
|
// Check if it's the same values we had
|
||||||
|
if !reflect.DeepEqual(c.ContractCommunities, response.ContractCommunities) ||
|
||||||
|
!reflect.DeepEqual(c.ContractFeaturedCommunities, response.ContractFeaturedCommunities) ||
|
||||||
|
!reflect.DeepEqual(c.UnknownCommunities, response.UnknownCommunities) {
|
||||||
|
// One of the communities is different, send the updated response
|
||||||
|
m.config.messengerSignalsHandler.SendCuratedCommunitiesUpdate(response)
|
||||||
|
|
||||||
|
// Update the values
|
||||||
|
c.ContractCommunities = response.ContractCommunities
|
||||||
|
c.ContractFeaturedCommunities = response.ContractFeaturedCommunities
|
||||||
|
c.UnknownCommunities = response.UnknownCommunities
|
||||||
|
}
|
||||||
|
mu.Unlock()
|
||||||
|
|
||||||
|
if len(response.UnknownCommunities) == 0 {
|
||||||
|
fetchResultsHistory = append(fetchResultsHistory, fetchSuccess)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
fetchResultsHistory = append(fetchResultsHistory, fetchHasUnknowns)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//keep only 2 last fetch results
|
||||||
|
if len(fetchResultsHistory) > 2 {
|
||||||
|
fetchResultsHistory = fetchResultsHistory[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
timeTillNextUpdate := calcTimeTillNextUpdate(fetchResultsHistory)
|
||||||
|
logger.Debug("Next curated communities update will happen in", zap.Duration("timeTillNextUpdate", timeTillNextUpdate))
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-time.After(timeTillNextUpdate):
|
||||||
|
case <-m.quit:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func calcTimeTillNextUpdate(fetchResultsHistory []int) time.Duration {
|
||||||
|
// TODO lower this back again once the real curated community contract is up
|
||||||
|
// The current contract contains communities that are no longer accessible on waku
|
||||||
|
const shortTimeout = 30 * time.Second
|
||||||
|
const averageTimeout = 60 * time.Second
|
||||||
|
const longTimeout = 300 * time.Second
|
||||||
|
|
||||||
|
twoConsecutiveErrors := (len(fetchResultsHistory) == 2 &&
|
||||||
|
fetchResultsHistory[0] == fetchError &&
|
||||||
|
fetchResultsHistory[1] == fetchError)
|
||||||
|
|
||||||
|
twoConsecutiveHasUnknowns := (len(fetchResultsHistory) == 2 &&
|
||||||
|
fetchResultsHistory[0] == fetchHasUnknowns &&
|
||||||
|
fetchResultsHistory[1] == fetchHasUnknowns)
|
||||||
|
|
||||||
|
var timeTillNextUpdate time.Duration
|
||||||
|
|
||||||
|
if twoConsecutiveErrors || twoConsecutiveHasUnknowns {
|
||||||
|
timeTillNextUpdate = longTimeout
|
||||||
|
} else {
|
||||||
|
switch fetchResultsHistory[len(fetchResultsHistory)-1] {
|
||||||
|
case fetchError:
|
||||||
|
timeTillNextUpdate = shortTimeout
|
||||||
|
case fetchSuccess:
|
||||||
|
timeTillNextUpdate = longTimeout
|
||||||
|
case fetchHasUnknowns:
|
||||||
|
timeTillNextUpdate = averageTimeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return timeTillNextUpdate
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) CuratedCommunities() (*communities.KnownCommunitiesResponse, error) {
|
||||||
|
if m.contractMaker == nil {
|
||||||
|
m.logger.Warn("contract maker not initialized")
|
||||||
|
return nil, errors.New("contract maker not initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
testNetworksEnabled, err := m.settings.GetTestNetworksEnabled()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
chainID := uint64(10) // Optimism Mainnet
|
||||||
|
if testNetworksEnabled {
|
||||||
|
chainID = 420 // Optimism Goerli
|
||||||
|
}
|
||||||
|
|
||||||
|
directory, err := m.contractMaker.NewDirectory(chainID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
callOpts := &bind.CallOpts{Context: context.Background(), Pending: false}
|
||||||
|
|
||||||
|
curatedCommunities, err := directory.GetCommunities(callOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var communityIDs []types.HexBytes
|
||||||
|
for _, c := range curatedCommunities {
|
||||||
|
communityIDs = append(communityIDs, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := m.communitiesManager.GetStoredDescriptionForCommunities(communityIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
featuredCommunities, err := directory.GetFeaturedCommunities(callOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range featuredCommunities {
|
||||||
|
response.ContractFeaturedCommunities = append(response.ContractFeaturedCommunities, types.HexBytes(c).String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use mechanism to obtain shard from community ID (https://github.com/status-im/status-desktop/issues/12585)
|
||||||
|
var unknownCommunities []communities.CommunityShard
|
||||||
|
for _, u := range response.UnknownCommunities {
|
||||||
|
unknownCommunities = append(unknownCommunities, communities.CommunityShard{
|
||||||
|
CommunityID: u,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
go m.requestCommunitiesFromMailserver(unknownCommunities)
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user