go-waku/waku/v2/protocol/enr/shards.go

144 lines
3.3 KiB
Go
Raw Normal View History

2023-04-20 18:51:13 +00:00
package enr
import (
"errors"
2023-04-20 18:51:13 +00:00
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/enr"
"github.com/waku-org/go-waku/waku/v2/protocol"
)
func deleteShardingENREntries(localnode *enode.LocalNode) {
localnode.Delete(enr.WithEntry(ShardingBitVectorEnrField, struct{}{}))
localnode.Delete(enr.WithEntry(ShardingIndicesListEnrField, struct{}{}))
}
func WithWakuRelayShardList(rs protocol.RelayShards) ENROption {
2023-04-25 16:09:55 +00:00
return func(localnode *enode.LocalNode) error {
value, err := rs.ShardList()
2023-04-25 16:09:55 +00:00
if err != nil {
return err
}
deleteShardingENREntries(localnode)
2023-04-25 16:09:55 +00:00
localnode.Set(enr.WithEntry(ShardingIndicesListEnrField, value))
return nil
2023-04-20 18:51:13 +00:00
}
}
2023-04-25 16:09:55 +00:00
func WithWakuRelayShardingBitVector(rs protocol.RelayShards) ENROption {
return func(localnode *enode.LocalNode) error {
deleteShardingENREntries(localnode)
2023-04-25 16:09:55 +00:00
localnode.Set(enr.WithEntry(ShardingBitVectorEnrField, rs.BitVector()))
return nil
}
2023-04-20 18:51:13 +00:00
}
func WithWakuRelaySharding(rs protocol.RelayShards) ENROption {
2023-04-25 16:09:55 +00:00
return func(localnode *enode.LocalNode) error {
if len(rs.ShardIDs) >= 64 {
2023-04-25 16:09:55 +00:00
return WithWakuRelayShardingBitVector(rs)(localnode)
}
return WithWakuRelayShardList(rs)(localnode)
2023-04-20 18:51:13 +00:00
}
}
func WithWakuRelayShardingTopics(topics ...string) ENROption {
return func(localnode *enode.LocalNode) error {
rs, err := protocol.TopicsToRelayShards(topics...)
if err != nil {
return err
}
if len(rs) != 1 {
return errors.New("expected a single RelayShards")
}
return WithWakuRelaySharding(rs[0])(localnode)
}
}
2023-04-20 18:51:13 +00:00
// ENR record accessors
func RelayShardList(record *enr.Record) (*protocol.RelayShards, error) {
2023-04-20 18:51:13 +00:00
var field []byte
if err := record.Load(enr.WithEntry(ShardingIndicesListEnrField, &field)); err != nil {
if enr.IsNotFound(err) {
return nil, nil
}
return nil, err
2023-04-20 18:51:13 +00:00
}
res, err := protocol.FromShardList(field)
2023-04-20 18:51:13 +00:00
if err != nil {
return nil, err
}
return &res, nil
}
2023-06-20 20:39:20 +00:00
func RelayShardingBitVector(record *enr.Record) (*protocol.RelayShards, error) {
2023-04-20 18:51:13 +00:00
var field []byte
if err := record.Load(enr.WithEntry(ShardingBitVectorEnrField, &field)); err != nil {
2023-06-20 20:39:20 +00:00
if enr.IsNotFound(err) {
return nil, nil
}
return nil, err
2023-04-20 18:51:13 +00:00
}
res, err := protocol.FromBitVector(field)
if err != nil {
return nil, err
}
return &res, nil
}
2023-06-20 20:39:20 +00:00
func RelaySharding(record *enr.Record) (*protocol.RelayShards, error) {
res, err := RelayShardList(record)
2023-04-20 18:51:13 +00:00
if err != nil {
return nil, err
}
if res != nil {
return res, nil
}
2023-06-20 20:39:20 +00:00
return RelayShardingBitVector(record)
2023-04-20 18:51:13 +00:00
}
// Utils
2023-06-20 20:39:20 +00:00
func ContainsShard(record *enr.Record, cluster uint16, index uint16) bool {
2023-04-20 18:51:13 +00:00
if index > protocol.MaxShardIndex {
return false
}
2023-06-20 20:39:20 +00:00
rs, err := RelaySharding(record)
2023-04-20 18:51:13 +00:00
if err != nil {
return false
}
return rs.Contains(cluster, index)
}
func ContainsShardWithWakuTopic(record *enr.Record, topic protocol.WakuPubSubTopic) bool {
if shardTopic, err := protocol.ToShardPubsubTopic(topic); err != nil {
2023-04-20 18:51:13 +00:00
return false
} else {
return ContainsShard(record, shardTopic.Cluster(), shardTopic.Shard())
2023-04-20 18:51:13 +00:00
}
2023-06-20 20:39:20 +00:00
}
2023-04-20 18:51:13 +00:00
2023-06-20 20:39:20 +00:00
func ContainsRelayShard(record *enr.Record, topic protocol.StaticShardingPubsubTopic) bool {
return ContainsShardWithWakuTopic(record, topic)
2023-04-20 18:51:13 +00:00
}
2023-06-20 20:39:20 +00:00
func ContainsShardTopic(record *enr.Record, topic string) bool {
shardTopic, err := protocol.ToWakuPubsubTopic(topic)
2023-04-20 18:51:13 +00:00
if err != nil {
return false
}
return ContainsShardWithWakuTopic(record, shardTopic)
2023-04-20 18:51:13 +00:00
}