Skip to content

Commit

Permalink
add endpoint for calculating the next electionId of an organization
Browse files Browse the repository at this point in the history
  • Loading branch information
jordipainan committed Nov 27, 2023
1 parent f4ad7f2 commit 465a207
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 0 deletions.
12 changes: 12 additions & 0 deletions api/api_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,18 @@ type Validator struct {
Score uint32 `json:"score"`
}

type NextElectionID struct {
OrganizationID types.HexBytes `json:"organizationId"`
CensusOrigin int32 `json:"censusOrigin"`
EnvelopeType struct {
Serial bool `json:"serial"`
Anonymous bool `json:"anonymous"`
EncryptedVotes bool `json:"encryptedVotes"`
UniqueValues bool `json:"uniqueValues"`
CostFromWeight bool `json:"costFromWeight"`
} `json:"envelopeType"`
}

// Protobuf wrappers

type VoteMode struct {
Expand Down
54 changes: 54 additions & 0 deletions api/elections.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ func (a *API) enableElectionHandlers() error {
return err
}

if err := a.Endpoint.RegisterMethod(
"/elections/id",
"POST",
apirest.MethodAccessTypePublic,
a.nextElectionIDHandler,
); err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -667,3 +676,48 @@ func (a *API) electionFilterPaginatedHandler(msg *apirest.APIdata, ctx *httprout
}
return ctx.Send(data, apirest.HTTPstatusOK)
}

// nextElectionIDHandler
//
// @Summary Get next election ID
// @Description nextElectionIDHandler
// @Tags Elections
// @Accept json
// @Produce json
// @Param transaction body NextElectionID true "OrganizationID, CensusOrigin and EnvelopeType"
// @Success 200 {object} object{electionID=string}
// @Router /elections/id [post]
func (a *API) nextElectionIDHandler(msg *apirest.APIdata, ctx *httprouter.HTTPContext) error {
body := &NextElectionID{}
if err := json.Unmarshal(msg.Data, body); err != nil {
return err
}
process := &models.Process{
EntityId: body.OrganizationID,
CensusOrigin: models.CensusOrigin(body.CensusOrigin),
EnvelopeType: &models.EnvelopeType{
Serial: body.EnvelopeType.Serial,
Anonymous: body.EnvelopeType.Anonymous,
EncryptedVotes: body.EnvelopeType.EncryptedVotes,
UniqueValues: body.EnvelopeType.UniqueValues,
CostFromWeight: body.EnvelopeType.CostFromWeight,
},
}
pid, err := processid.BuildProcessID(
process,
a.vocapp.State,
)
if err != nil {
return ErrCantParseElectionID.WithErr(err)
}

data, err := json.Marshal(struct {
ElectionID string `json:"electionID"`
}{
ElectionID: pid.String(),
})
if err != nil {
return ErrMarshalingServerJSONFailed.WithErr(err)
}
return ctx.Send(data, apirest.HTTPstatusOK)
}
35 changes: 35 additions & 0 deletions apiclient/election.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,3 +453,38 @@ func (c *HTTPclient) ElectionPrice(election *api.ElectionDescription) (uint64, e
}
return price.Price, nil
}

// NextElectionID gets the next election ID for an organization.
// POST /elections/id
func (c *HTTPclient) NextElectionID(organizationID types.HexBytes, censusOrigin int32, envelopeType *models.EnvelopeType) (string, error) {
body := &api.NextElectionID{
OrganizationID: organizationID,
CensusOrigin: censusOrigin,
EnvelopeType: struct {
Serial bool `json:"serial"`
Anonymous bool `json:"anonymous"`
EncryptedVotes bool `json:"encryptedVotes"`
UniqueValues bool `json:"uniqueValues"`
CostFromWeight bool `json:"costFromWeight"`
}{
Serial: envelopeType.Serial,
Anonymous: envelopeType.Anonymous,
EncryptedVotes: envelopeType.EncryptedVotes,
UniqueValues: envelopeType.UniqueValues,
CostFromWeight: envelopeType.CostFromWeight,
},
}
resp, code, err := c.Request(HTTPPOST, body, "elections", "id")
if err != nil {
return "", err
}
if code != apirest.HTTPstatusOK {
return "", fmt.Errorf("%s: %d (%s)", errCodeNot200, code, resp)
}

var electionID string
if err := json.Unmarshal(resp, &electionID); err != nil {
return "", err
}
return electionID, nil
}
52 changes: 52 additions & 0 deletions test/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,3 +647,55 @@ func sendTokensTx(t testing.TB, c *testutil.TestHTTPclient,
resp, code := c.Request("POST", tx, "chain", "transactions")
qt.Assert(t, code, qt.Equals, 200, qt.Commentf("response: %s", resp))
}

func TestAPINextElectionID(t *testing.T) {
server := testcommon.APIserver{}
server.Start(t,
api.ChainHandler,
api.CensusHandler,
api.VoteHandler,
api.AccountHandler,
api.ElectionHandler,
api.WalletHandler,
)

c := testutil.NewTestHTTPclient(t, server.ListenAddr, nil)

// Block 1
server.VochainAPP.AdvanceTestBlock()
waitUntilHeight(t, c, 1)

// create a new account
signer := createAccount(t, c, server, 80)

// Block 2
server.VochainAPP.AdvanceTestBlock()
waitUntilHeight(t, c, 2)

// create request for calling api elections/id
body := api.NextElectionID{
OrganizationID: signer.Address().Bytes(),
CensusOrigin: int32(models.CensusOrigin_OFF_CHAIN_TREE_WEIGHTED.Number()),
EnvelopeType: struct {
Serial bool `json:"serial"`
Anonymous bool `json:"anonymous"`
EncryptedVotes bool `json:"encryptedVotes"`
UniqueValues bool `json:"uniqueValues"`
CostFromWeight bool `json:"costFromWeight"`
}{
Serial: true,
Anonymous: true,
EncryptedVotes: true,
UniqueValues: true,
CostFromWeight: true,
},
}
resp, code := c.Request("POST", body, "elections", "id")
qt.Assert(t, code, qt.Equals, 200, qt.Commentf("response: %s", resp))

nextElectionID := struct {
ElectionID string `json:"electionID"`
}{}
err := json.Unmarshal(resp, &nextElectionID)
qt.Assert(t, err, qt.IsNil)
}

0 comments on commit 465a207

Please sign in to comment.