-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathclient.go
161 lines (132 loc) · 4.44 KB
/
client.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package main
import (
"context"
"fmt"
"os"
es "github.com/go-errors/errors"
"gopkg.in/alecthomas/kingpin.v2"
"github.com/filecoin-project/mir/stdtypes"
"github.com/filecoin-project/mir"
"github.com/filecoin-project/mir/pkg/bcb"
mirCrypto "github.com/filecoin-project/mir/pkg/crypto"
"github.com/filecoin-project/mir/pkg/logging"
"github.com/filecoin-project/mir/pkg/modules"
"github.com/filecoin-project/mir/pkg/net/grpc"
trantorpbtypes "github.com/filecoin-project/mir/pkg/pb/trantorpb/types"
grpctools "github.com/filecoin-project/mir/pkg/util/grpc"
)
const (
// Base port number for the nodes to listen to messages from each other.
// The nodes will listen on ports starting from nodeBasePort through nodeBasePort+3.
nodeBasePort = 10000
// The number of nodes participating in the chat.
nodeNumber = 4
// The index of the leader node of BCB.
leaderNode = 0
)
// parsedArgs represents parsed command-line parameters passed to the program.
type parsedArgs struct {
// ID of this node.
// The package github.com/hyperledger-labs/mir/pkg/types defines this and other types used by the library.
OwnID stdtypes.NodeID
// If set, print debug output to stdout.
Verbose bool
// If set, print trace output to stdout.
Trace bool
}
func main() {
if err := run(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func run() error {
args := parseArgs(os.Args)
// Initialize logger that will be used throughout the code to print log messages.
var logger logging.Logger
if args.Trace {
logger = logging.ConsoleTraceLogger // Print trace-level info.
} else if args.Verbose {
logger = logging.ConsoleDebugLogger // Print debug-level info in verbose mode.
} else {
logger = logging.ConsoleWarnLogger // Only print errors and warnings by default.
}
// IDs of nodes that are part of the system.
// This example uses a static configuration of nodeNumber nodes.
nodeIDs := make([]stdtypes.NodeID, nodeNumber)
for i := 0; i < nodeNumber; i++ {
nodeIDs[i] = stdtypes.NewNodeIDFromInt(i)
}
// Construct membership, remembering own address.
membership := &trantorpbtypes.Membership{make(map[stdtypes.NodeID]*trantorpbtypes.NodeIdentity)} // nolint:govet
var ownAddr stdtypes.NodeAddress
for i := range nodeIDs {
id := stdtypes.NewNodeIDFromInt(i)
addr := grpctools.NewDummyMultiaddr(i + nodeBasePort)
if id == args.OwnID {
ownAddr = addr
}
membership.Nodes[id] = &trantorpbtypes.NodeIdentity{
Id: id,
Addr: addr.String(),
Key: nil,
Weight: "1",
}
}
transportModule, err := grpc.NewTransport(grpc.DefaultParams(), args.OwnID, ownAddr.String(), logger, nil)
if err != nil {
return es.Errorf("failed to get network transport %w", err)
}
if err := transportModule.Start(); err != nil {
return es.Errorf("could not start network transport: %w", err)
}
transportModule.Connect(membership)
bcbModule := bcb.NewModule(
bcb.ModuleConfig{
Self: "bcb",
Consumer: "control",
Net: "net",
Crypto: "crypto",
},
&bcb.ModuleParams{
InstanceUID: []byte("testing instance"),
AllNodes: nodeIDs,
Leader: nodeIDs[leaderNode],
},
args.OwnID,
)
// control module reads the user input from the console and processes it.
control := newControlModule( /*isLeader=*/ args.OwnID == nodeIDs[leaderNode])
m := map[stdtypes.ModuleID]modules.Module{
"net": transportModule,
"crypto": mirCrypto.New(&mirCrypto.DummyCrypto{DummySig: []byte{0}}),
"bcb": bcbModule,
"control": control,
}
// create a Mir node
node, err := mir.NewNode("client", mir.DefaultNodeConfig().WithLogger(logger), m, nil)
if err != nil {
return es.Errorf("error creating a Mir node: %w", err)
}
// run the node
err = node.Run(context.Background())
if err != nil {
return es.Errorf("error running node: %w", err)
}
return nil
}
// Parses the command-line arguments and returns them in a params struct.
func parseArgs(args []string) *parsedArgs {
app := kingpin.New("chat-demo", "Small chat application to demonstrate the usage of the Mir library.")
verbose := app.Flag("verbose", "Verbose mode.").Short('v').Bool()
trace := app.Flag("trace", "Very verbose mode.").Bool()
ownID := app.Arg("id", "ID of this node").Required().String()
if _, err := app.Parse(args[1:]); err != nil { // Skip args[0], which is the name of the program, not an argument.
app.FatalUsage("could not parse arguments: %v\n", err)
}
return &parsedArgs{
OwnID: stdtypes.NodeID(*ownID),
Verbose: *verbose,
Trace: *trace,
}
}