From 73db598fc3b1420e7cc8d3d8f2bd0f23666e8407 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Thu, 10 Oct 2024 15:23:34 +0200 Subject: [PATCH] @Pierluca's and @jbsv's comments - change name from SuffragiaBlock to SuffragiaBatch - add prefixed.Snapshot --- contracts/evoting/json/forms.go | 30 ++++++++--------- contracts/evoting/mod.go | 3 ++ contracts/evoting/types/election.go | 50 +++++++++++++++-------------- integration/performance_test.go | 4 +-- 4 files changed, 46 insertions(+), 41 deletions(-) diff --git a/contracts/evoting/json/forms.go b/contracts/evoting/json/forms.go index 2640cfd80..56cc737e8 100644 --- a/contracts/evoting/json/forms.go +++ b/contracts/evoting/json/forms.go @@ -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) } @@ -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 } diff --git a/contracts/evoting/mod.go b/contracts/evoting/mod.go index b431bc445..7d7f0ae63 100644 --- a/contracts/evoting/mod.go +++ b/contracts/evoting/mod.go @@ -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" @@ -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) diff --git a/contracts/evoting/types/election.go b/contracts/evoting/types/election.go index bc2d41383..60cc762f6 100644 --- a/contracts/evoting/types/election.go +++ b/contracts/evoting/types/election.go @@ -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 @@ -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. @@ -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. @@ -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 @@ -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 { diff --git a/integration/performance_test.go b/integration/performance_test.go index 9d4e542a9..85d8c86bb 100644 --- a/integration/performance_test.go +++ b/integration/performance_test.go @@ -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" @@ -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.