2024-01-06 14:45:00 +00:00
|
|
|
package protocol
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/ed25519"
|
|
|
|
"fmt"
|
|
|
|
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
|
|
|
"git.lumeweb.com/LumeWeb/libs5-go/net"
|
2024-01-07 09:30:03 +00:00
|
|
|
"git.lumeweb.com/LumeWeb/libs5-go/storage"
|
2024-01-06 14:45:00 +00:00
|
|
|
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
|
|
|
"git.lumeweb.com/LumeWeb/libs5-go/utils"
|
|
|
|
"github.com/emirpasic/gods/sets/hashset"
|
|
|
|
"github.com/vmihailenco/msgpack/v5"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
2024-01-30 03:25:21 +00:00
|
|
|
var _ IncomingMessage = (*StorageLocation)(nil)
|
2024-01-06 14:45:00 +00:00
|
|
|
|
|
|
|
type StorageLocation struct {
|
|
|
|
hash *encoding.Multihash
|
|
|
|
kind int
|
|
|
|
expiry int64
|
|
|
|
parts []string
|
|
|
|
publicKey []byte
|
|
|
|
signature []byte
|
2024-01-30 03:25:21 +00:00
|
|
|
HandshakeRequirement
|
2024-01-06 14:45:00 +00:00
|
|
|
}
|
|
|
|
|
2024-01-09 18:58:11 +00:00
|
|
|
func NewStorageLocation() *StorageLocation {
|
2024-01-13 16:22:01 +00:00
|
|
|
sl := &StorageLocation{}
|
|
|
|
|
|
|
|
sl.SetRequiresHandshake(true)
|
|
|
|
|
|
|
|
return sl
|
2024-01-09 18:58:11 +00:00
|
|
|
}
|
|
|
|
|
2024-01-30 03:25:21 +00:00
|
|
|
func (s *StorageLocation) DecodeMessage(dec *msgpack.Decoder, message IncomingMessageData) error {
|
2024-01-09 19:54:59 +00:00
|
|
|
// nop, we use the incoming message -> original already stored
|
2024-01-06 14:45:00 +00:00
|
|
|
return nil
|
|
|
|
}
|
2024-01-30 03:25:21 +00:00
|
|
|
func (s *StorageLocation) HandleMessage(message IncomingMessageData) error {
|
2024-01-29 04:39:40 +00:00
|
|
|
msg := message.Original
|
2024-01-29 06:55:36 +00:00
|
|
|
services := message.Services
|
2024-01-29 04:39:40 +00:00
|
|
|
peer := message.Peer
|
2024-01-29 06:55:36 +00:00
|
|
|
logger := message.Logger
|
2024-01-09 19:54:59 +00:00
|
|
|
|
|
|
|
hash := encoding.NewMultihash(msg[1:34]) // Replace NewMultihash with appropriate function
|
2024-01-06 14:45:00 +00:00
|
|
|
|
2024-01-09 19:54:59 +00:00
|
|
|
typeOfData := msg[34]
|
2024-01-06 14:45:00 +00:00
|
|
|
|
2024-01-09 19:54:59 +00:00
|
|
|
expiry := utils.DecodeEndian(msg[35:39])
|
2024-01-06 14:45:00 +00:00
|
|
|
|
2024-01-09 19:54:59 +00:00
|
|
|
partCount := msg[39]
|
2024-01-06 14:45:00 +00:00
|
|
|
|
|
|
|
parts := []string{}
|
|
|
|
cursor := 40
|
|
|
|
for i := 0; i < int(partCount); i++ {
|
2024-01-09 19:54:59 +00:00
|
|
|
length := utils.DecodeEndian(msg[cursor : cursor+2])
|
2024-01-06 14:45:00 +00:00
|
|
|
cursor += 2
|
2024-01-24 16:10:16 +00:00
|
|
|
if len(msg) < cursor+int(length) {
|
|
|
|
return fmt.Errorf("Invalid message")
|
|
|
|
}
|
2024-01-09 19:54:59 +00:00
|
|
|
part := string(msg[cursor : cursor+int(length)])
|
2024-01-06 14:45:00 +00:00
|
|
|
parts = append(parts, part)
|
|
|
|
cursor += int(length)
|
|
|
|
}
|
|
|
|
|
2024-01-09 19:54:59 +00:00
|
|
|
cursor++
|
|
|
|
|
|
|
|
publicKey := msg[cursor : cursor+33]
|
|
|
|
signature := msg[cursor+33:]
|
2024-01-06 14:45:00 +00:00
|
|
|
|
|
|
|
if types.HashType(publicKey[0]) != types.HashTypeEd25519 { // Replace CID_HASH_TYPES_ED25519 with actual constant
|
|
|
|
return fmt.Errorf("Unsupported public key type %d", publicKey[0])
|
|
|
|
}
|
|
|
|
|
2024-01-09 19:54:59 +00:00
|
|
|
if !ed25519.Verify(publicKey[1:], msg[:cursor], signature) {
|
2024-01-06 14:45:00 +00:00
|
|
|
return fmt.Errorf("Signature verification failed")
|
|
|
|
}
|
|
|
|
|
|
|
|
nodeId := encoding.NewNodeId(publicKey)
|
|
|
|
|
2024-01-07 08:13:35 +00:00
|
|
|
// Assuming `node` is an instance of your NodeImpl structure
|
2024-01-29 06:55:36 +00:00
|
|
|
err := services.Storage().AddStorageLocation(hash, nodeId, storage.NewStorageLocation(int(typeOfData), parts, int64(expiry)), msg) // Implement AddStorageLocation
|
2024-01-06 14:45:00 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Failed to add storage location: %s", err)
|
|
|
|
}
|
|
|
|
|
2024-01-08 17:40:40 +00:00
|
|
|
hashStr, err := hash.ToString()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-01-06 14:45:00 +00:00
|
|
|
var list *hashset.Set
|
2024-01-29 06:55:36 +00:00
|
|
|
listVal, ok := services.P2P().HashQueryRoutingTable().Get(hashStr) // Implement HashQueryRoutingTable method
|
2024-01-06 14:45:00 +00:00
|
|
|
if !ok {
|
|
|
|
list = hashset.New()
|
2024-01-08 17:40:40 +00:00
|
|
|
} else {
|
|
|
|
list = listVal.(*hashset.Set)
|
2024-01-06 14:45:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, peerIdVal := range list.Values() {
|
|
|
|
peerId := peerIdVal.(*encoding.NodeId)
|
|
|
|
|
|
|
|
if peerId.Equals(nodeId) || peerId.Equals(peer) {
|
|
|
|
continue
|
|
|
|
}
|
2024-01-08 17:40:40 +00:00
|
|
|
peerIdStr, err := peerId.ToString()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-01-29 06:55:36 +00:00
|
|
|
if peerVal, ok := services.P2P().Peers().Get(peerIdStr); ok {
|
2024-01-06 14:45:00 +00:00
|
|
|
foundPeer := peerVal.(net.Peer)
|
2024-01-09 19:54:59 +00:00
|
|
|
err := foundPeer.SendMessage(msg)
|
2024-01-06 14:45:00 +00:00
|
|
|
if err != nil {
|
2024-01-29 06:55:36 +00:00
|
|
|
logger.Error("Failed to send message", zap.Error(err))
|
2024-01-06 14:45:00 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-29 06:55:36 +00:00
|
|
|
services.P2P().HashQueryRoutingTable().Remove(hash.HashCode())
|
2024-01-06 14:45:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|