Commit f44211b4 authored by Anders Jensen Løvig's avatar Anders Jensen Løvig
Browse files

Add Server to Election

parent 647be9a1
Pipeline #21764 failed with stages
in 1 minute and 4 seconds
......@@ -71,20 +71,15 @@ func init() {
servers := len(server.Config.Servers)
required := (servers / 2) + 1
config := &election.Config{
Server: server.Server,
ServerID: election.UniqueID(serialNumber.String()),
Voters: 10,
Servers: servers,
RequiredServers: required,
Deadline: time.Now().Add(30 * time.Second),
CloseCallback: closeCallback,
TallyCallback: tallyCallback,
ResultCallback: resultCallback,
}
server.Election = election.NewElection(config)
server.Server.OnClientMessage(election.MsgBallot, server.Election.OnBallot)
server.Server.OnServerMessage(election.MsgClosing, server.Election.OnClose)
server.Server.OnServerMessage(election.MsgTally, server.Election.OnTally)
}
func startServer() {
......@@ -125,7 +120,6 @@ func main() {
time.Sleep(1 * time.Second) // To let servers connect before starting election
startElection()
<-server.Done // Closed
<-server.Done // Result
time.Sleep(1 * time.Second) // Grace period
......@@ -133,18 +127,6 @@ func main() {
server.Server.Close()
}
func closeCallback(reason election.Reason) {
msgClosed := network.NewMessage(election.MsgClosing)
server.Server.Broadcast(msgClosed)
server.Done <- true
}
func tallyCallback(tally *election.Tally) {
msgTally := network.NewMessage(election.MsgTally, tally)
server.Server.Broadcast(msgTally)
}
func resultCallback(result *election.Result) {
if result == nil {
log.Printf("Main: no votes received")
......
package main
import (
"bsc-shamir/crypto/common"
"bsc-shamir/election"
"bsc-shamir/network"
"bufio"
......@@ -95,6 +96,12 @@ func main() {
}
ballots := election.CreateBallots(t, xs, big.NewInt(vote))
params := common.DefaultParams()
for id, b := range ballots {
if !b.Verify(params) {
log.Fatal("Main: fatal: could not verify ballot for server", id)
}
}
sendBallots(ballots)
// Wait for acknowledgements or timeout
......
......@@ -12,6 +12,10 @@ const (
g = "2"
h = "3"
// 256 bits
// p = "113725176798010050451165288258759946268131239693032262275611886693367245547103"
// q = "56862588399005025225582644129379973134065619846516131137805943346683622773551"
// 2048 bits
p = "df0df2d4d4320d6f562ddf3ef2ba7b96463e8ba2b6d965a7b377521434dea91ffc299287efc0d495e58fc33cacfc02d2ed819c83bd66b4ebf5373a001adf1b18b0a80c4df6bb372708479c3afa081ae913b99c6b74906b6d497f7752a54869d9542097b98e7373d6643cc3533197ff8160a7d79791ce3e5f53c43a89cf8f4f9fd3afd5cdc6902784daa97715ef73ba8f5d69c2f8e0e901c35917b8d081f38ae07e59df580515fdcb38a718de4c512353658f4e622ed88b7379893907e7d59df22c427f4b04fd0bfbb40e650907c25d61f0cdc7dc2f677841ee06a60ed8206e7ec46684a8716a9470aa19cb221ea1bce00f59067ce4439fd04be0c370e9f3f487"
q = "6f86f96a6a1906b7ab16ef9f795d3dcb231f45d15b6cb2d3d9bba90a1a6f548ffe14c943f7e06a4af2c7e19e567e016976c0ce41deb35a75fa9b9d000d6f8d8c58540626fb5d9b938423ce1d7d040d7489dcce35ba4835b6a4bfbba952a434ecaa104bdcc739b9eb321e61a998cbffc0b053ebcbc8e71f2fa9e21d44e7c7a7cfe9d7eae6e34813c26d54bb8af7b9dd47aeb4e17c707480e1ac8bdc6840f9c5703f2cefac028afee59c538c6f262891a9b2c7a731176c45b9bcc49c83f3eacef916213fa5827e85fdda07328483e12eb0f866e3ee17b3bc20f70353076c10373f6233425438b54a38550ce5910f50de7007ac833e7221cfe825f061b874f9fa43"
......
......@@ -3,6 +3,7 @@ package election
import (
"bsc-shamir/crypto/common"
"bsc-shamir/network"
"errors"
"log"
"math/big"
......@@ -71,6 +72,8 @@ type Status struct {
type Election struct {
sync.Mutex
// The network Server on which this election is held.
server *network.Server
// ID of the server running the election
ServerID UniqueID
// Participants contains information about how many participants
......@@ -87,24 +90,19 @@ type Election struct {
Deadline time.Time
// Struct containing server status about the election.
Status Status
// Called when the election is closed locally
closeCallback func(Reason)
// Called when a enough servers (Participants.RequiredServers) have closed
tallyCallback func(*Tally)
// Called when the final result is available
resultCallback func(*Result)
}
// Config for creating elections
type Config struct {
ServerID UniqueID `json:"id"`
Voters int `json:"voters"`
Servers int `json:"servers"`
RequiredServers int `json:"required"`
Deadline time.Time `json:"deadline"`
CloseCallback func(Reason) `json:"-"`
TallyCallback func(*Tally) `json:"-"`
ResultCallback func(*Result) `json:"-"`
Server *network.Server `json:"-"`
ServerID UniqueID `json:"id"`
Voters int `json:"voters"`
Servers int `json:"servers"`
RequiredServers int `json:"required"`
Deadline time.Time `json:"deadline"`
ResultCallback func(*Result) `json:"-"`
}
// Result represents the result of an election
......@@ -121,7 +119,8 @@ func NewElection(config *Config) *Election {
if !success {
log.Fatal(success)
}
return &Election{
e := &Election{
server: config.Server,
ServerID: config.ServerID,
Participants: Participants{
Voters: config.Voters,
......@@ -138,11 +137,13 @@ func NewElection(config *Config) *Election {
TalliedServers: make(map[UniqueID]bool),
Turnout: make(map[UniqueID]bool),
},
closeCallback: config.CloseCallback,
tallyCallback: config.TallyCallback,
resultCallback: config.ResultCallback,
Mutex: sync.Mutex{},
}
config.Server.OnClientMessage(MsgBallot, e.OnBallot)
config.Server.OnServerMessage(MsgClosing, e.OnClose)
config.Server.OnServerMessage(MsgTally, e.OnTally)
return e
}
// Start the election, by opening for incomming ballots.
......@@ -184,7 +185,7 @@ func (election *Election) nextPhase(reason Reason) {
election.Status.Phase = PhaseCollecting
case PhaseCollecting:
election.Status.ClosedServers[election.ServerID] = true
election.closeCallback(reason)
election.server.Broadcast(network.NewMessage(MsgClosing))
// If more than required servers have closed, then we can skip the next phase
// Else we have to wait for more servers to close
......@@ -211,7 +212,7 @@ func (election *Election) nextPhase(reason Reason) {
panic(err) // This should never happen
}
election.tallyCallback(tally)
election.server.Broadcast(network.NewMessage(MsgTally, tally))
break
}
fallthrough
......
......@@ -202,8 +202,6 @@ func setupElection() *Election {
Servers: 3,
RequiredServers: 2,
Deadline: time.Now().Add(1 * time.Minute),
CloseCallback: func(reason Reason) {},
TallyCallback: func(tally *Tally) {},
ResultCallback: func(result *Result) {},
}
return NewElection(config)
......@@ -215,12 +213,12 @@ func testCloseCondition(t *testing.T, expectedReason Reason, expectedPhase Phase
timeout := make(chan bool, 1)
e := setupElection()
e.closeCallback = func(reason Reason) {
if reason != expectedReason {
t.Errorf("Unexpected close reason\n Expected: %s\n Actual: %s\n", expectedReason, reason)
}
close <- true
}
// e.closeCallback = func(reason Reason) {
// if reason != expectedReason {
// t.Errorf("Unexpected close reason\n Expected: %s\n Actual: %s\n", expectedReason, reason)
// }
// close <- true
// }
go func() {
time.Sleep(2 * time.Second)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment