65 lines
1.4 KiB
Go
65 lines
1.4 KiB
Go
package gossip
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/netip"
|
|
"time"
|
|
)
|
|
|
|
const PacketSize = 1232
|
|
|
|
// PullClient implements the stateful client (initiator) side of the gossip pull protocol.
|
|
type PullClient struct {
|
|
identity ed25519.PrivateKey
|
|
so udpSender
|
|
}
|
|
|
|
func NewPullClient(identity ed25519.PrivateKey, so udpSender) *PullClient {
|
|
return &PullClient{
|
|
identity: identity,
|
|
so: so,
|
|
}
|
|
}
|
|
|
|
func (p *PullClient) Pull(target netip.AddrPort) error {
|
|
filters := NewCrdsFilterSet(65536, MaxBloomSize)
|
|
for _, filter := range filters {
|
|
if err := p.sendPullRequest(target, filter); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p *PullClient) sendPullRequest(target netip.AddrPort, filter CrdsFilter) error {
|
|
msg := &Message__PullRequest{
|
|
Filter: filter,
|
|
Value: CrdsValue{
|
|
Data: &CrdsData__ContactInfo{
|
|
Value: ContactInfo{
|
|
Wallclock: uint64(time.Now().UnixMilli()),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
err := msg.Value.Sign(p.identity)
|
|
if err != nil {
|
|
panic("failed to sign pull request: " + err.Error())
|
|
}
|
|
|
|
packet, err := msg.BincodeSerialize()
|
|
if err != nil {
|
|
panic("failed to serialize packet: " + err.Error())
|
|
}
|
|
|
|
_, err = p.so.WriteToUDPAddrPort(packet, target)
|
|
return err
|
|
}
|
|
|
|
func (p *PullClient) HandlePullResponse(msg *Message__PullResponse, _ netip.AddrPort) {
|
|
jsonBuf, _ := json.MarshalIndent(msg, "", "\t")
|
|
fmt.Println(string(jsonBuf))
|
|
}
|