-
Notifications
You must be signed in to change notification settings - Fork 23
/
ebt.go
90 lines (74 loc) · 1.81 KB
/
ebt.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
84
85
86
87
88
89
90
// SPDX-FileCopyrightText: 2021 The Go-SSB Authors
//
// SPDX-License-Identifier: MIT
package ssb
import (
"encoding/json"
"fmt"
"strconv"
"strings"
refs "github.com/ssbc/go-ssb-refs"
)
// NetworkFrontier represents a set of feeds and their length
// The key is the canonical string representation (feed.Ref())
type NetworkFrontier map[string]Note
// Note informs about a feeds length and some control settings
type Note struct {
Seq int64
// Replicate (seq==-1) tells the peer that it doesn't want to hear about that feed
Replicate bool
// Receive controlls the eager push.
// a peer might want to know if there are updates but not directly get the messages
Receive bool
}
func (s Note) MarshalJSON() ([]byte, error) {
var i int64
if !s.Replicate {
return []byte("-1"), nil
}
i = int64(s.Seq)
if i == -1 { // -1 is margarets way of saying "no msgs in this feed"
i = 0
}
i = i << 1 // times 2 (to make room for the rx bit)
if s.Receive {
i |= 0
} else {
i |= 1
}
return []byte(strconv.FormatInt(i, 10)), nil
}
func (nf *NetworkFrontier) UnmarshalJSON(b []byte) error {
var dummy map[string]int64
if err := json.Unmarshal(b, &dummy); err != nil {
return err
}
var newMap = make(NetworkFrontier, len(dummy))
for fstr, i := range dummy {
// validate
feed, err := refs.ParseFeedRef(fstr)
if err != nil {
// just skip invalid feeds
continue
}
if feed.Algo() != refs.RefAlgoFeedSSB1 {
// skip other formats (TODO: gg support)
continue
}
var s Note
s.Replicate = i != -1
s.Receive = !(i&1 == 1)
s.Seq = int64(i >> 1)
newMap[fstr] = s
}
*nf = newMap
return nil
}
func (nf NetworkFrontier) String() string {
var sb strings.Builder
sb.WriteString("## Network Frontier:\n")
for feed, seq := range nf {
fmt.Fprintf(&sb, "\t%s:%+v\n", feed, seq)
}
return sb.String()
}