Replies: 2 comments
-
I’m a big fan in general. one suggestion I have is to ensure that fields/settings are only accessible if they are relevant. For example, in the election model we have a censusSize field, which a comment notes is only relevant to non-anonymous elections: https://github.com/vocdoni/dvote-protobuf/blob/1ac419517d30e0fd43002b66cb52d134daa3c758/src/protocol/election.proto#L24 I think situations like this can be confusing- I probably won’t be looking at comments in the protobuf models when implementing a component, so I might assume that censusSize is relevant and important to any process, and then encounter unknown bugs if I’m relying on what’s stored in this field. I definitely encountered bugs like this with our current architecture when implementing the app + explorer. Just a general design thought. Maybe in this specific situation we could allow the CensusProofs models to contain their own configs, where we could store CensusSize or any similar proof-specific setting in the future. |
Beta Was this translation helpful? Give feedback.
-
Another comment: with the way protobuf serializes/deserializes, would we be able to add new Proposal models in the future and still use these models to deserialize the existing/legacy elections we have stored? |
Beta Was this translation helpful? Give feedback.
-
A data-encoding protocol, intended to allow developing decentralized and fast-changing components within a flexible environment, where iterations can be made in a fault-tolerant fashion.
This proposal is in line with the ideas presented by @arnaucube, and also with some of the best practices of the Clean Architecture model.
This proposal is conceived to host the current and future developments, topologies and architectures.
Reasoning
The current flow in which models are defined (Vochain > rest of components), has brought friction and development issues, since other components learn about the schema's when the whole features are iin
master
, and reconsidering changes is a no-go. If changes are made to a JSON model or Vochain enum's, errors and mismatches don't appear until weeks or months later (sometimes before critical deadlines).The Vochain is acting as a source of truth, that all remote components are coupled against, even if data fields and internal edge cases are not relevant to them. This increases the chances on developers missing out.
Main ideas
In order to adopt a stronger development model for the future, the proposed path is to gradually replace the current data serialization and low-level JSON API's by a global set of protobuf models. Not all at once.
Defined in a project of its own in the first place, and implemented across the stack only after all the affected parties validate it. This should not imply changing the implementation of the Vochain. Just the transport adapters.
Proposed global models: https://github.com/vocdoni/dvote-protobuf/blob/draft/protocol-v2/src/protocol/
The data models involve two different domains:
For this proposal to be successful, there should be a Protocol coordinator, as suggested by @mvdan. This is, someone with the role of assuring the consistency and soundness of the whole spec and accommodating the feedback of everyone before any changes are made.
In addition to this:
Key benefits:
omitempty
in every potential GW response fieldData transport examples (fragment)
Every interaction is a message body, which may or may not be signed (similar to what the Vochain does now, but fitted to act as the only communication wrapper for all):
A message body can have one of:
Transaction
,TransactionReceipt
,Request
andResponse
. Theseoneof
definitions act as an implicit enum. Only relevantTransaction
fields will appear, only relevantRequest
fields will exist, etc. In additioin, all these payloads are self-contained, 100% signable and verifiable, irregardless of JSON marshaling, field ordering, string encoding, etc.All the potential operations are immediately visible to the developer.
For each one of them, we can easily find the definition of their
Request
and their correspondingResponse
. One is always next to each other. Naming leaves no doubt about the hierarchy.In general, responses can be a success or an error, each with their own fields and an optional body (similar for transactions)
Wrapped data examples (fragment)
An election can be defined as follows. It can specify many censuses, for which voters need to provide a proof in their ballot.
Each election has N proposals (questions). Each question can have a different type of voting mechanic, have its own status (ready, paused, ended, etc)
Certain flags like the
Privacy
ones can be defined here:When the
censusProof
isZK_SNARKS
orZK_SNARKS_PREREGISTER
, all voters are expected to submit aProofZkSnark
for each census entry. Otherwise, a plain proofs likeProofArbo
,ProofCSP
,StorageProofErc20
, etc are expected. See below.When voting, a ballot can have two use cases: Signed (non-anonymous census proofs) or Anonymous (using ZK proofs, nothing is signed):
Votes can be sent all at once or be submitted proposal by proposal (step by step).
The kind of
Proof
models will be 1:1 mapped to the respectiveCensus
'es used to define the election.If the
primaryCensus
defined aCensusArbo
model like:Then, voters will need to provide a first proof like:
If the
secondaryCensus
defined aCensusErc20
(PoH or similar) like:Then voters are expected to encode a
ProofErc20
like:Important note: The ballot will be signed by one wallet only. This means that all proofs need to refer to that wallet's address.
The beauty of this is that new types of censuses, are not coupled with existing models and schemes. Censuses can also be defined as
CensusNone
, in which case, nothing is required.Simmilarly, depending on the type of aggregation requested when defining a
Proposal
above (ApprovalProposal
,SingleChoiceProposal
,QuadraticProposal
,RankedProposal
andSpreadProposal
), theirResults
will have an according data representation.This way, consumers get an already friendly representation for most of the cases. The only case where aggregation is a bit more involved is when representing
RankedResult
's. There, we need to express the votes that each option received for each potential weight, but the rest are unaffected.Beta Was this translation helpful? Give feedback.
All reactions