status-go/protocol/messenger_community_storenodes.go
Pablo Lopez 3f19972c8e
enable custom community storenodes (#4532)
* enable custom community store nodes

* fix

* fix

* fix

* fix

* cleanup

* fix

* migration

* fix

* cleanup

* fix

* cleanup

* fix

* fix

* cleanup

* message to update the community storenodes

* rename

* fix test

* wait for availability only if global storenode

* fix test

* fix typo

* sync community storenodes

* remove unused

* add tests

* fix imports

* fix todo

* unused

* pr comments

* pr feedback

* revert merge deleted

* fix lint

* fix db and perform ms request

* typo

* fix log

* fix go imports

* refactor handle message

* cleanup public message

* add tests

* fix test

* cleanup test

* fix test

* avoid making one file to big to keep codeclimate from complaining

* fix lint

* revert

* Update protocol/storenodes/database.go

Co-authored-by: richΛrd <info@richardramos.me>

* Update protocol/messenger_mailserver_cycle.go

Co-authored-by: richΛrd <info@richardramos.me>

* PR comment

* fix tx

* proto files

* pr comment

---------

Co-authored-by: richΛrd <info@richardramos.me>
2024-02-20 17:49:39 +02:00

93 lines
3.2 KiB
Go

package protocol
import (
"context"
"errors"
"github.com/golang/protobuf/proto"
"go.uber.org/zap"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/communities"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/storenodes"
v1protocol "github.com/status-im/status-go/protocol/v1"
)
func (m *Messenger) sendCommunityPublicStorenodesInfo(community *communities.Community, snodes storenodes.Storenodes) error {
if !community.IsControlNode() {
return communities.ErrNotControlNode
}
clock, _ := m.getLastClockWithRelatedChat()
pb := &protobuf.CommunityStorenodes{
Clock: clock,
CommunityId: community.ID(),
Storenodes: snodes.ToProtobuf(),
ChainId: communities.CommunityDescriptionTokenOwnerChainID(community.Description()),
}
snPayload, err := proto.Marshal(pb)
if err != nil {
return err
}
signature, err := crypto.Sign(crypto.Keccak256(snPayload), community.PrivateKey())
if err != nil {
return err
}
signedStorenodesInfo := &protobuf.CommunityPublicStorenodesInfo{
Signature: signature,
Payload: snPayload,
}
signedPayload, err := proto.Marshal(signedStorenodesInfo)
if err != nil {
return err
}
rawMessage := common.RawMessage{
Payload: signedPayload,
Sender: community.PrivateKey(),
SkipEncryptionLayer: true,
MessageType: protobuf.ApplicationMetadataMessage_COMMUNITY_PUBLIC_STORENODES_INFO,
PubsubTopic: community.PubsubTopic(),
}
_, err = m.sender.SendPublic(context.Background(), community.IDString(), rawMessage)
return err
}
// HandleCommunityPublicStorenodesInfo will process the control message sent by the community owner on updating the community storenodes for his community (sendCommunityPublicStorenodesInfo).
// The message will be received by many peers that are not interested on that community, so if we don't have this community in our DB we just ignore this message.
func (m *Messenger) HandleCommunityPublicStorenodesInfo(state *ReceivedMessageState, a *protobuf.CommunityPublicStorenodesInfo, statusMessage *v1protocol.StatusMessage) error {
sn := &protobuf.CommunityStorenodes{}
err := proto.Unmarshal(a.Payload, sn)
if err != nil {
return err
}
logger := m.logger.Named("HandleCommunityPublicStorenodesInfo").With(zap.String("communityID", types.EncodeHex(sn.CommunityId)))
err = m.verifyCommunitySignature(a.Payload, a.Signature, sn.CommunityId, sn.ChainId)
if err != nil {
logger.Error("failed to verify community signature", zap.Error(err))
return err
}
// verify if we are interested in this control message
_, err = m.communitiesManager.GetByID(sn.CommunityId)
if err != nil {
if errors.Is(err, communities.ErrOrgNotFound) {
logger.Debug("ignoring control message, community not found")
return nil
}
logger.Error("failed get community by id", zap.Error(err))
return err
}
if err := m.communityStorenodes.UpdateStorenodesInDB(sn.CommunityId, storenodes.FromProtobuf(sn.Storenodes, sn.Clock), sn.Clock); err != nil {
logger.Error("failed to update storenodes for community", zap.Error(err))
return err
}
return nil
}