Skip to content

Commit

Permalink
@pierluca's and @jbsv's comments
Browse files Browse the repository at this point in the history
- change name from SuffragiaBlock to SuffragiaBatch
- add prefixed.Snapshot
  • Loading branch information
ineiti committed Oct 10, 2024
1 parent db54223 commit 73db598
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 41 deletions.
30 changes: 15 additions & 15 deletions contracts/evoting/json/forms.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ func (formFormat) Encode(ctx serde.Context, message serde.Message) ([]byte, erro
}
}

suffragias := make([]string, len(m.SuffragiaIDs))
for i, suf := range m.SuffragiaIDs {
suffragias := make([]string, len(m.SuffragiaStoreKeys))
for i, suf := range m.SuffragiaStoreKeys {
suffragias[i] = hex.EncodeToString(suf)
}

Expand Down Expand Up @@ -146,19 +146,19 @@ func (formFormat) Decode(ctx serde.Context, data []byte) (serde.Message, error)
}

return types.Form{
Configuration: formJSON.Configuration,
FormID: formJSON.FormID,
Status: types.Status(formJSON.Status),
Pubkey: pubKey,
BallotSize: formJSON.BallotSize,
SuffragiaIDs: suffragias,
SuffragiaHashes: suffragiaHashes,
BallotCount: formJSON.BallotCount,
ShuffleInstances: shuffleInstances,
ShuffleThreshold: formJSON.ShuffleThreshold,
PubsharesUnits: pubSharesSubmissions,
DecryptedBallots: formJSON.DecryptedBallots,
Roster: roster,
Configuration: formJSON.Configuration,
FormID: formJSON.FormID,
Status: types.Status(formJSON.Status),
Pubkey: pubKey,
BallotSize: formJSON.BallotSize,
SuffragiaStoreKeys: suffragias,
SuffragiaHashes: suffragiaHashes,
BallotCount: formJSON.BallotCount,
ShuffleInstances: shuffleInstances,
ShuffleThreshold: formJSON.ShuffleThreshold,
PubsharesUnits: pubSharesSubmissions,
DecryptedBallots: formJSON.DecryptedBallots,
Roster: roster,
}, nil
}

Expand Down
3 changes: 3 additions & 0 deletions contracts/evoting/mod.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"go.dedis.ch/dela/core/execution/native"
"go.dedis.ch/dela/core/ordering/cosipbft/authority"
"go.dedis.ch/dela/core/store"
"go.dedis.ch/dela/core/store/prefixed"
"go.dedis.ch/dela/serde"
"go.dedis.ch/dela/serde/json"

Expand Down Expand Up @@ -198,6 +199,8 @@ func (c Contract) Execute(snap store.Snapshot, step execution.Step) error {
return xerrors.Errorf("%q not found in tx arg", CmdArg)
}

snap = prefixed.NewSnapshot(ContractUID, snap)

switch Command(cmd) {
case CmdCreateForm:
err = c.cmd.createForm(snap, step)
Expand Down
50 changes: 26 additions & 24 deletions contracts/evoting/types/election.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ const (
Canceled Status = 6
)

// BallotsPerBlock to improve performance, so that (de)serializing only touches
// BallotsPerBatch to improve performance, so that (de)serializing only touches
// 100 ballots at a time.
var BallotsPerBlock = uint32(100)
var BallotsPerBatch = uint32(100)

// TestCastBallots if true, automatically fills every block with ballots.
// TestCastBallots if true, automatically fills every batch with ballots.
var TestCastBallots = false

// formFormat contains the supported formats for the form. Right now
Expand Down Expand Up @@ -78,15 +78,15 @@ type Form struct {
// to pad smaller ballots such that all ballots cast have the same size
BallotSize int

// SuffragiaIDs holds a slice of IDs to slices of SuffragiaIDs.
// SuffragiaStoreKeys holds a slice of storage-keys to 0 or more Suffragia.
// This is to optimize the time it takes to (De)serialize a Form.
SuffragiaIDs [][]byte
SuffragiaStoreKeys [][]byte

// BallotCount is the total number of ballots cast, including double
// ballots.
BallotCount uint32

// SuffragiaHashes holds a slice of hashes to all SuffragiaIDs.
// SuffragiaHashes holds a slice of hashes to all SuffragiaStoreKeys.
// LG: not really sure if this is needed. In case a Form has also to be
// proven to be correct outside the nodes, the hashes are definitely
// needed.
Expand Down Expand Up @@ -204,8 +204,9 @@ func (e *Form) ChunksPerBallot() int {
// CastVote stores the new vote in the memory.
func (s *Form) CastVote(ctx serde.Context, st store.Snapshot, userID string, ciphervote Ciphervote) error {
var suff Suffragia
var blockID []byte
if s.BallotCount%BallotsPerBlock == 0 {
var batchID []byte

if s.BallotCount%BallotsPerBatch == 0 {
// Need to create a random ID for storing the ballots.
// H( formID | ballotcount )
// should be random enough, even if it's previsible.
Expand All @@ -216,42 +217,43 @@ func (s *Form) CastVote(ctx serde.Context, st store.Snapshot, userID string, cip
h := sha256.New()
h.Write(id)
binary.LittleEndian.PutUint32(id, s.BallotCount)
blockID = h.Sum(id[0:4])[:32]
err = st.Set(blockID, []byte{})
batchID = h.Sum(id[0:4])[:32]

err = st.Set(batchID, []byte{})
if err != nil {
return xerrors.Errorf("couldn't store new ballot block: %v", err)
return xerrors.Errorf("couldn't store new ballot batch: %v", err)
}
s.SuffragiaIDs = append(s.SuffragiaIDs, blockID)
s.SuffragiaStoreKeys = append(s.SuffragiaStoreKeys, batchID)
s.SuffragiaHashes = append(s.SuffragiaHashes, []byte{})
} else {
blockID = s.SuffragiaIDs[len(s.SuffragiaIDs)-1]
buf, err := st.Get(blockID)
batchID = s.SuffragiaStoreKeys[len(s.SuffragiaStoreKeys)-1]
buf, err := st.Get(batchID)
if err != nil {
return xerrors.Errorf("couldn't get ballots block: %v", err)
return xerrors.Errorf("couldn't get ballots batch: %v", err)
}
format := suffragiaFormat.Get(ctx.GetFormat())
ctx = serde.WithFactory(ctx, CiphervoteKey{}, CiphervoteFactory{})
msg, err := format.Decode(ctx, buf)
if err != nil {
return xerrors.Errorf("couldn't unmarshal ballots block in cast: %v", err)
return xerrors.Errorf("couldn't unmarshal ballots batch in cast: %v", err)
}
suff = msg.(Suffragia)
}

suff.CastVote(userID, ciphervote)
if TestCastBallots {
for i := uint32(1); i < BallotsPerBlock; i++ {
for i := uint32(1); i < BallotsPerBatch; i++ {
suff.CastVote(fmt.Sprintf("%s-%d", userID, i), ciphervote)
}
s.BallotCount += BallotsPerBlock - 1
s.BallotCount += BallotsPerBatch - 1
}
buf, err := suff.Serialize(ctx)
if err != nil {
return xerrors.Errorf("couldn't marshal ballots block: %v", err)
return xerrors.Errorf("couldn't marshal ballots batch: %v", err)
}
err = st.Set(blockID, buf)
err = st.Set(batchID, buf)
if err != nil {
xerrors.Errorf("couldn't set new ballots block: %v", err)
xerrors.Errorf("couldn't set new ballots batch: %v", err)
}
s.BallotCount += 1
return nil
Expand All @@ -263,16 +265,16 @@ func (s *Form) CastVote(ctx serde.Context, st store.Snapshot, userID string, cip
// the latest ballot.
func (s *Form) Suffragia(ctx serde.Context, rd store.Readable) (Suffragia, error) {
var suff Suffragia
for _, id := range s.SuffragiaIDs {
for _, id := range s.SuffragiaStoreKeys {
buf, err := rd.Get(id)
if err != nil {
return suff, xerrors.Errorf("couldn't get ballot block: %v", err)
return suff, xerrors.Errorf("couldn't get ballot batch: %v", err)
}
format := suffragiaFormat.Get(ctx.GetFormat())
ctx = serde.WithFactory(ctx, CiphervoteKey{}, CiphervoteFactory{})
msg, err := format.Decode(ctx, buf)
if err != nil {
return suff, xerrors.Errorf("couldn't unmarshal ballots block in cast: %v", err)
return suff, xerrors.Errorf("couldn't unmarshal ballots batch in cast: %v", err)
}
suffTmp := msg.(Suffragia)
for i, uid := range suffTmp.UserIDs {
Expand Down
4 changes: 2 additions & 2 deletions integration/performance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func customVotesScenario(b *testing.B, stuffing bool) {
types.TestCastBallots = false
}()
numVotes = 10000
transactions = numVotes / int(types.BallotsPerBlock)
transactions = numVotes / int(types.BallotsPerBatch)
}

adminID := "I am an admin"
Expand Down Expand Up @@ -169,7 +169,7 @@ func customVotesScenario(b *testing.B, stuffing bool) {
b.Logf("Submitting shares took: %v", durationPubShares)
b.Logf("Decryption took: %v", durationDecrypt)

require.Len(b, form.DecryptedBallots, len(castedVotes)*int(types.BallotsPerBlock))
require.Len(b, form.DecryptedBallots, len(castedVotes)*int(types.BallotsPerBatch))

// There will be a lot of supplementary ballots, but at least the ones that were
// cast by the test should be present.
Expand Down

0 comments on commit 73db598

Please sign in to comment.