Files
mvds/main.go
Andrea Maria Piana 87839f9f3a Don't retun error on removing state when receiving messages
When receiving messages the state for the message is removed.
If no state is found an error was thrown.
This should not cause an error as that's an ok scenario.
Also changes the parsing of the flags from init to a custom method, as I
bumped in this issue https://github.com/golang/go/issues/31859
2019-10-07 12:35:15 +02:00

171 lines
3.3 KiB
Go

package main
import (
"crypto/rand"
"flag"
"fmt"
"log"
math "math/rand"
"time"
"github.com/vacp2p/mvds/node"
"github.com/vacp2p/mvds/peers"
"github.com/vacp2p/mvds/state"
"github.com/vacp2p/mvds/store"
"github.com/vacp2p/mvds/transport"
"go.uber.org/zap"
)
var (
offline int
nodeCount int
communicating int
sharing int
interval int64
interactive int
)
func parseFlags() {
flag.IntVar(&offline, "offline", 90, "percentage of time a node is offline")
flag.IntVar(&nodeCount, "nodes", 3, "amount of nodes")
flag.IntVar(&communicating, "communicating", 2, "amount of nodes sending messages")
flag.IntVar(&sharing, "sharing", 2, "amount of nodes each node shares with")
flag.Int64Var(&interval, "interval", 5, "seconds between messages")
flag.IntVar(&interactive, "interactive", 3, "amount of nodes to use INTERACTIVE mode, the rest will be BATCH") // @todo should probably just be how many nodes are interactive
flag.Parse()
}
func main() {
parseFlags()
// @todo validate flags
transports := make([]*transport.ChannelTransport, 0)
input := make([]chan transport.Packet, 0)
nodes := make([]*node.Node, 0)
for i := 0; i < nodeCount; i++ {
in := make(chan transport.Packet)
t := transport.NewChannelTransport(offline, in)
input = append(input, in)
transports = append(transports, t)
mode := node.INTERACTIVE
if i+1 >= interactive {
mode = node.BATCH
}
node, err := createNode(t, peerID(), mode)
if err != nil {
log.Printf("Could not create node: %+v\n", err)
}
nodes = append(
nodes,
node,
)
}
group := groupId()
// @todo add multiple groups, only one or so nodes in every group so there is overlap
// @todo maybe dms?
for i, n := range nodes {
peers := selectPeers(len(nodes), i, sharing)
for _, p := range peers {
peer := nodes[p].ID
transports[i].AddOutput(peer, input[p])
_ = n.AddPeer(group, peer)
log.Printf("%x sharing with %x", n.ID[:4], peer[:4])
}
}
for _, n := range nodes {
n.Start(1 * time.Second)
}
chat(group, nodes[:communicating-1]...)
}
func selectPeers(nodeCount int, currentNode int, sharing int) []int {
peers := make([]int, 0)
OUTER:
for len(peers) != sharing {
math.Seed(time.Now().UnixNano())
i := math.Intn(nodeCount)
if i == currentNode {
continue
}
for _, p := range peers {
if i == p {
continue OUTER
}
}
peers = append(peers, i)
}
return peers
}
func createNode(transport transport.Transport, id state.PeerID, mode node.Mode) (*node.Node, error) {
ds := store.NewDummyStore()
logger, err := zap.NewDevelopment()
if err != nil {
return nil, err
}
return node.NewNode(
ds,
transport,
state.NewSyncState(),
Calc,
0,
id,
mode,
peers.NewMemoryPersistence(),
logger,
), nil
}
func chat(group state.GroupID, nodes ...*node.Node) {
for {
time.Sleep(time.Duration(interval) * time.Second)
for _, n := range nodes {
_, err := n.AppendMessage(group, []byte(fmt.Sprintf("%x testing", n.ID)))
if err != nil {
fmt.Println(err)
}
}
}
}
func Calc(count uint64, epoch int64) int64 {
return epoch + int64(count*2)
}
func peerID() state.PeerID {
bytes := make([]byte, 65)
_, _ = rand.Read(bytes)
id := state.PeerID{}
copy(id[:], bytes)
return id
}
func groupId() state.GroupID {
bytes := make([]byte, 32)
_, _ = rand.Read(bytes)
id := state.GroupID{}
copy(id[:], bytes)
return id
}