Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
DisSys Inc.
bsc-shamir
Commits
389848b9
Commit
389848b9
authored
Jun 03, 2020
by
Anders Jensen Løvig
Browse files
nextPhase: began refacter
parent
f44211b4
Changes
2
Hide whitespace changes
Inline
Side-by-side
election/ballot.go
View file @
389848b9
...
...
@@ -14,6 +14,7 @@ import (
"log"
"math/big"
"sync"
"time"
"crypto"
...
...
@@ -24,10 +25,11 @@ import (
// Ballot represents a share to be submitted to a vote counter.
type
Ballot
struct
{
ID
uuid
.
UUID
`json:"id"`
Share
*
pedersen
.
Share
`json:"share"`
Commits
pedersen
.
Proof
`json:"commits"`
Proofs
[
2
]
*
sigma
.
Proof
`json:"proofs"`
ID
uuid
.
UUID
`json:"id"`
Timestamp
time
.
Time
`json:"timestamp`
Share
*
pedersen
.
Share
`json:"share"`
Commits
pedersen
.
Proof
`json:"commits"`
Proofs
[
2
]
*
sigma
.
Proof
`json:"proofs"`
}
// BallotBox collects ballots from voters
...
...
@@ -58,13 +60,16 @@ func CreateBallots(t int, xs []*big.Int, vote *big.Int) map[UniqueID]*Ballot {
shares
,
commits
:=
pedersen
.
NewParams
(
params
)
.
Create
(
t
,
xs
,
vote
,
binder
)
proof
:=
sigma
.
NewParams
(
params
)
.
Prove
(
vote
,
binder
,
commits
[
0
])
timestamp
:=
time
.
Now
()
ballots
:=
make
(
map
[
UniqueID
]
*
Ballot
)
for
_
,
share
:=
range
shares
{
ballots
[
UniqueID
(
share
.
X
.
String
())]
=
&
Ballot
{
ID
:
uuid
.
New
(),
Share
:
share
,
Commits
:
commits
,
Proofs
:
proof
,
ID
:
uuid
.
New
(),
Timestamp
:
timestamp
,
Share
:
share
,
Commits
:
commits
,
Proofs
:
proof
,
}
}
...
...
election/election.go
View file @
389848b9
...
...
@@ -17,11 +17,12 @@ type UniqueID string
type
Reason
string
const
(
ReasonStarting
=
"starting election"
ReasonDeadline
=
"deadline reached"
ReasonVotes
=
"all votes received"
ReasonAgreement
=
"majority agrees"
ReasonTally
=
"received enough tallies"
ReasonStarting
=
"starting election"
ReasonDeadline
=
"deadline reached"
ReasonCloseTimeout
=
"timeout while waiting for late ballots"
ReasonVotes
=
"all votes received"
ReasonAgreement
=
"majority agrees"
ReasonTally
=
"received enough tallies"
)
// Phase of an election
...
...
@@ -31,6 +32,7 @@ type Phase int
const
(
PhaseNotStarted
Phase
=
iota
PhaseCollecting
// When voters can send ballots
PhaseCloseWait
// When server waits after close
PhaseClosed
// When waiting for other servers to close
PhaseTallying
// When tallying
PhaseResult
// When a result is available
...
...
@@ -63,6 +65,8 @@ type Participants struct {
// Status contains the current status of the election.
type
Status
struct
{
Phase
Phase
PhaseChannel
chan
bool
CloseTime
time
.
Time
ClosedServers
map
[
UniqueID
]
bool
// Map of closed servers
TalliedServers
map
[
UniqueID
]
bool
// Map of servers who tallied
Turnout
map
[
UniqueID
]
bool
// Map of voters who voted
...
...
@@ -71,6 +75,7 @@ type Status struct {
// Election is an abstraction of an election.
type
Election
struct
{
sync
.
Mutex
Config
*
Config
// The network Server on which this election is held.
server
*
network
.
Server
...
...
@@ -103,6 +108,9 @@ type Config struct {
RequiredServers
int
`json:"required"`
Deadline
time
.
Time
`json:"deadline"`
ResultCallback
func
(
*
Result
)
`json:"-"`
// Delay between closing and tallying
CloseSleep
time
.
Duration
}
// Result represents the result of an election
...
...
@@ -120,6 +128,7 @@ func NewElection(config *Config) *Election {
log
.
Fatal
(
success
)
}
e
:=
&
Election
{
Config
:
config
,
server
:
config
.
Server
,
ServerID
:
config
.
ServerID
,
Participants
:
Participants
{
...
...
@@ -133,6 +142,7 @@ func NewElection(config *Config) *Election {
Deadline
:
config
.
Deadline
,
Status
:
Status
{
Phase
:
PhaseNotStarted
,
PhaseChannel
:
make
(
chan
bool
,
1
),
ClosedServers
:
make
(
map
[
UniqueID
]
bool
),
TalliedServers
:
make
(
map
[
UniqueID
]
bool
),
Turnout
:
make
(
map
[
UniqueID
]
bool
),
...
...
@@ -184,15 +194,46 @@ func (election *Election) nextPhase(reason Reason) {
log
.
Println
(
"==================== Collecting ===================="
)
election
.
Status
.
Phase
=
PhaseCollecting
case
PhaseCollecting
:
log
.
Println
(
"====================== Closed ======================"
)
// The closed phase is twofold. If the reason for closing is another
// than all votes received (ReasonVotes), then we must wait for late
// ballots.
// Next we wait for more than required servers to close.
// Close election and tell other servers
election
.
Status
.
CloseTime
=
time
.
Now
()
election
.
Status
.
ClosedServers
[
election
.
ServerID
]
=
true
election
.
server
.
Broadcast
(
network
.
NewMessage
(
MsgClosing
))
// Wait for late ballots if not all votes received.
if
reason
!=
ReasonVotes
{
log
.
Println
(
"Election: waiting 5 seconds for late ballots"
)
election
.
Status
.
Phase
=
PhaseCloseWait
go
func
(
e
*
Election
)
{
var
reason
Reason
// Wait for either 5 seconds or PhaseChannel is set.
select
{
case
<-
time
.
After
(
5
*
time
.
Second
)
:
reason
=
ReasonCloseTimeout
case
<-
e
.
Status
.
PhaseChannel
:
reason
=
ReasonVotes
}
// Then next phase
e
.
Lock
()
defer
e
.
Unlock
()
// Actually close the election
e
.
Status
.
Phase
=
PhaseClosed
e
.
nextPhase
(
reason
)
}(
election
)
break
}
// If more than required servers have closed, then we can skip the next phase
// Else we have to wait for more servers to close
if
len
(
election
.
Status
.
ClosedServers
)
<
election
.
Participants
.
RequiredServers
{
// Not enough servers to tally.
log
.
Println
(
"====================== Closed ======================"
)
election
.
Status
.
Phase
=
PhaseClosed
n
:=
election
.
Participants
.
RequiredServers
-
len
(
election
.
Status
.
ClosedServers
)
log
.
Printf
(
"Election: waiting for %d more servers to close
\n
"
,
n
)
break
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment