@maci-protocol/core 0.0.0-ci.1e276ed
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +595 -0
- package/LICENSE +22 -0
- package/README.md +107 -0
- package/build/ts/MaciState.d.ts +64 -0
- package/build/ts/MaciState.d.ts.map +1 -0
- package/build/ts/MaciState.js +127 -0
- package/build/ts/MaciState.js.map +1 -0
- package/build/ts/Poll.d.ts +221 -0
- package/build/ts/Poll.d.ts.map +1 -0
- package/build/ts/Poll.js +1087 -0
- package/build/ts/Poll.js.map +1 -0
- package/build/ts/index.d.ts +6 -0
- package/build/ts/index.d.ts.map +1 -0
- package/build/ts/index.js +17 -0
- package/build/ts/index.js.map +1 -0
- package/build/ts/utils/constants.d.ts +6 -0
- package/build/ts/utils/constants.d.ts.map +1 -0
- package/build/ts/utils/constants.js +9 -0
- package/build/ts/utils/constants.js.map +1 -0
- package/build/ts/utils/errors.d.ts +27 -0
- package/build/ts/utils/errors.d.ts.map +1 -0
- package/build/ts/utils/errors.js +35 -0
- package/build/ts/utils/errors.js.map +1 -0
- package/build/ts/utils/types.d.ts +206 -0
- package/build/ts/utils/types.d.ts.map +1 -0
- package/build/ts/utils/types.js +3 -0
- package/build/ts/utils/types.js.map +1 -0
- package/build/ts/utils/utils.d.ts +38 -0
- package/build/ts/utils/utils.d.ts.map +1 -0
- package/build/ts/utils/utils.js +46 -0
- package/build/ts/utils/utils.js.map +1 -0
- package/build/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# `maci-core`
|
|
2
|
+
|
|
3
|
+
[![NPM Package][core-npm-badge]][core-npm-link]
|
|
4
|
+
[![Actions Status][core-actions-badge]][core-actions-link]
|
|
5
|
+
|
|
6
|
+
This submodule assists with handling key business logic functions and
|
|
7
|
+
processes.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
One may conceive of MACI as a state machine with 1) data and 2) functions which
|
|
12
|
+
transform said data. This makes it easier to reason about the system, write
|
|
13
|
+
tests, and implement functionality. It also allows us to implement the smart
|
|
14
|
+
contracts in discrete components which are easy to test.
|
|
15
|
+
|
|
16
|
+
To this end, this submodule exposes a `MaciState` class and a `Poll` class.
|
|
17
|
+
Developers should instantiate objects from these classes to test MACI. For
|
|
18
|
+
instance, [`MACI.test.ts`](https://github.com/privacy-scaling-explorations/maci/blob/dev/packages/contracts/tests/MACI.test.ts) creates a
|
|
19
|
+
`MaciState` object and every time it interacts with the MACI smart contract, it
|
|
20
|
+
mirrors said interaction on the `MaciState` and `Poll`. As such, the developer
|
|
21
|
+
can then use their helper functions like `maciState.signUp()`,
|
|
22
|
+
`poll.publishMessage`, `poll.processMessages()`, and `poll.tallyVotes()` to
|
|
23
|
+
step through the various stages of the MACI flow.
|
|
24
|
+
|
|
25
|
+
## `MaciState`
|
|
26
|
+
|
|
27
|
+
### Key functions
|
|
28
|
+
|
|
29
|
+
#### **`signUp`**
|
|
30
|
+
|
|
31
|
+
Accepts a user's public key and creates a new state leaf and ballot leaf.
|
|
32
|
+
|
|
33
|
+
In testing, whenever a test suite submits a `signUp()` transaction, it should
|
|
34
|
+
call `maciState.signUp()` as well, so that the off-chain representation of MACI
|
|
35
|
+
is kept up to date.
|
|
36
|
+
|
|
37
|
+
In production, `genMaciStateFromContract()` in
|
|
38
|
+
[`genMaciState.ts`](https://github.com/privacy-scaling-explorations/maci/blob/dev/contracts/ts/genMaciState.ts) uses this function when it
|
|
39
|
+
scans a MACI contract's event log for signups, so as to bring its `MaciState`
|
|
40
|
+
instance up to date.
|
|
41
|
+
|
|
42
|
+
#### **`deployPoll`**
|
|
43
|
+
|
|
44
|
+
Creates a new `Poll`. This should be done whenever the MACI contract's
|
|
45
|
+
`deployPoll()` function is called.
|
|
46
|
+
|
|
47
|
+
### Helper functions
|
|
48
|
+
|
|
49
|
+
#### **`copy`**
|
|
50
|
+
|
|
51
|
+
A function that deep-copies an object.
|
|
52
|
+
|
|
53
|
+
### Key data structures
|
|
54
|
+
|
|
55
|
+
#### **`stateTree`**
|
|
56
|
+
|
|
57
|
+
`stateTree` is a quinary Merkle tree, chosen over a binary tree due to the gas and circuit constraints associated with the Poseidon hash function ([details here][ethresearch-link]). Each leaf in this tree represents a participant's public key, their voice credit balance and the block timestamp at which they signed up. The tree features a configurable depth and an arity of five, with insertions starting at index 1. The zeroth leaf is reserved as a security measure against denial-of-service attacks.
|
|
58
|
+
|
|
59
|
+
## **`Poll`**
|
|
60
|
+
|
|
61
|
+
A `Poll` is an off-chain representation of a Poll. In testing, `Poll` instances
|
|
62
|
+
should mirror their on-chain counterparts.
|
|
63
|
+
|
|
64
|
+
### Key functions
|
|
65
|
+
|
|
66
|
+
#### **`publishMessage`**
|
|
67
|
+
|
|
68
|
+
Publishes a message by updating the message tree and message accumulation
|
|
69
|
+
queue.
|
|
70
|
+
|
|
71
|
+
#### **`processMessages`**
|
|
72
|
+
|
|
73
|
+
Processes a batch of messages and returns the inputs to the `processMessages`
|
|
74
|
+
circuit which can be used to prove correct execution.
|
|
75
|
+
|
|
76
|
+
#### **`tallyVotes`**
|
|
77
|
+
|
|
78
|
+
Tallies a batch of votes and returns the inputs to the `tallyVotes`
|
|
79
|
+
circuit which can be used to prove correct execution.
|
|
80
|
+
|
|
81
|
+
### Helper functions
|
|
82
|
+
|
|
83
|
+
#### **`copy`**
|
|
84
|
+
|
|
85
|
+
Deep-copies and returns this object.
|
|
86
|
+
|
|
87
|
+
### Key data structures
|
|
88
|
+
|
|
89
|
+
#### **`messageTree`**
|
|
90
|
+
|
|
91
|
+
`messageTree` is also a quinary Merkle tree. Each message in this tree represents an encrypted command, such as a user casting a vote in a poll or changing their public key.
|
|
92
|
+
|
|
93
|
+
## Testing
|
|
94
|
+
|
|
95
|
+
For more details about testing please refer to the [tests documentation](https://maci.pse.dev/docs/testing).
|
|
96
|
+
|
|
97
|
+
[core-npm-badge]: https://img.shields.io/npm/v/maci-core.svg
|
|
98
|
+
[core-npm-link]: https://www.npmjs.com/package/maci-core
|
|
99
|
+
[core-actions-badge]: https://github.com/privacy-scaling-explorations/maci/actions/workflows/core-build.yml/badge.svg
|
|
100
|
+
[core-actions-link]: https://github.com/privacy-scaling-explorations/maci/actions?query=workflow%3Acore
|
|
101
|
+
[ethresearch-link]: https://ethresear.ch/t/gas-and-circuit-constraint-benchmarks-of-binary-and-quinary-incremental-merkle-trees-using-the-poseidon-hash-function/7446
|
|
102
|
+
|
|
103
|
+
## Directory Structure
|
|
104
|
+
|
|
105
|
+
- `ts/`: The home for our core classes, `MaciState` and `Poll`
|
|
106
|
+
- `ts/utls/`: Contains supporting utilities
|
|
107
|
+
- `ts/__tests__/`: A dedicated test suite directory
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { IncrementalQuinTree } from "@maci-protocol/crypto";
|
|
2
|
+
import { PubKey, type Keypair } from "@maci-protocol/domainobjs";
|
|
3
|
+
import type { IJsonMaciState, IMaciState, TreeDepths } from "./utils/types";
|
|
4
|
+
import { Poll } from "./Poll";
|
|
5
|
+
/**
|
|
6
|
+
* A representation of the MACI contract.
|
|
7
|
+
*/
|
|
8
|
+
export declare class MaciState implements IMaciState {
|
|
9
|
+
polls: Map<bigint, Poll>;
|
|
10
|
+
pubKeys: PubKey[];
|
|
11
|
+
stateTreeDepth: number;
|
|
12
|
+
stateTree?: IncrementalQuinTree;
|
|
13
|
+
numSignUps: number;
|
|
14
|
+
pollBeingProcessed?: boolean;
|
|
15
|
+
currentPollBeingProcessed?: bigint;
|
|
16
|
+
/**
|
|
17
|
+
* Constructs a new MaciState object.
|
|
18
|
+
* @param stateTreeDepth - The depth of the state tree.
|
|
19
|
+
*/
|
|
20
|
+
constructor(stateTreeDepth: number);
|
|
21
|
+
/**
|
|
22
|
+
* Sign up a user with the given public key.
|
|
23
|
+
* @param pubKey - The public key of the user.
|
|
24
|
+
* @returns The index of the newly signed-up user in the state tree.
|
|
25
|
+
*/
|
|
26
|
+
signUp(pubKey: PubKey): number;
|
|
27
|
+
/**
|
|
28
|
+
* Deploy a new poll with the given parameters.
|
|
29
|
+
* @param pollEndTimestamp - The Unix timestamp at which the poll ends.
|
|
30
|
+
* @param treeDepths - The depths of the tree.
|
|
31
|
+
* @param messageBatchSize - The batch size for processing messages.
|
|
32
|
+
* @param coordinatorKeypair - The keypair of the MACI round coordinator.
|
|
33
|
+
* @param voteOptions - The number of vote options for this poll.
|
|
34
|
+
* @returns The index of the newly deployed poll.
|
|
35
|
+
*/
|
|
36
|
+
deployPoll(pollEndTimestamp: bigint, treeDepths: TreeDepths, messageBatchSize: number, coordinatorKeypair: Keypair, voteOptions: bigint): bigint;
|
|
37
|
+
/**
|
|
38
|
+
* Deploy a null poll.
|
|
39
|
+
*/
|
|
40
|
+
deployNullPoll(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Create a deep copy of the MaciState object.
|
|
43
|
+
* @returns A new instance of the MaciState object with the same properties.
|
|
44
|
+
*/
|
|
45
|
+
copy: () => MaciState;
|
|
46
|
+
/**
|
|
47
|
+
* Check if the MaciState object is equal to another MaciState object.
|
|
48
|
+
* @param m - The MaciState object to compare.
|
|
49
|
+
* @returns True if the two MaciState objects are equal, false otherwise.
|
|
50
|
+
*/
|
|
51
|
+
equals: (m: MaciState) => boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Serialize the MaciState object to a JSON object.
|
|
54
|
+
* @returns A JSON object representing the MaciState object.
|
|
55
|
+
*/
|
|
56
|
+
toJSON(): IJsonMaciState;
|
|
57
|
+
/**
|
|
58
|
+
* Create a new MaciState object from a JSON object.
|
|
59
|
+
* @param json - The JSON object representing the MaciState object.
|
|
60
|
+
* @returns A new instance of the MaciState object with the properties from the JSON object.
|
|
61
|
+
*/
|
|
62
|
+
static fromJSON(json: IJsonMaciState): MaciState;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=MaciState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaciState.d.ts","sourceRoot":"","sources":["../../ts/MaciState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,EAAU,MAAM,2BAA2B,CAAC;AAEzE,OAAO,KAAK,EAAE,cAAc,EAAa,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEvF,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B;;GAEG;AACH,qBAAa,SAAU,YAAW,UAAU;IAE1C,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAA2B;IAGnD,OAAO,EAAE,MAAM,EAAE,CAAM;IAGvB,cAAc,EAAE,MAAM,CAAC;IAGvB,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAEhC,UAAU,SAAK;IAGf,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAEnC;;;OAGG;gBACS,cAAc,EAAE,MAAM;IAUlC;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAO9B;;;;;;;;OAQG;IACH,UAAU,CACR,gBAAgB,EAAE,MAAM,EACxB,UAAU,EAAE,UAAU,EACtB,gBAAgB,EAAE,MAAM,EACxB,kBAAkB,EAAE,OAAO,EAC3B,WAAW,EAAE,MAAM,GAClB,MAAM;IAiBT;;OAEG;IACH,cAAc,IAAI,IAAI;IAItB;;;OAGG;IACH,IAAI,QAAO,SAAS,CAQlB;IAEF;;;;OAIG;IACH,MAAM,GAAI,GAAG,SAAS,KAAG,OAAO,CAsB9B;IAEF;;;OAGG;IACH,MAAM,IAAI,cAAc;IAWxB;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS;CAgBjD"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MaciState = void 0;
|
|
4
|
+
const domainobjs_1 = require("@maci-protocol/domainobjs");
|
|
5
|
+
const Poll_1 = require("./Poll");
|
|
6
|
+
const constants_1 = require("./utils/constants");
|
|
7
|
+
/**
|
|
8
|
+
* A representation of the MACI contract.
|
|
9
|
+
*/
|
|
10
|
+
class MaciState {
|
|
11
|
+
/**
|
|
12
|
+
* Constructs a new MaciState object.
|
|
13
|
+
* @param stateTreeDepth - The depth of the state tree.
|
|
14
|
+
*/
|
|
15
|
+
constructor(stateTreeDepth) {
|
|
16
|
+
// a MaciState can hold multiple polls
|
|
17
|
+
this.polls = new Map();
|
|
18
|
+
// the public keys of the users
|
|
19
|
+
this.pubKeys = [];
|
|
20
|
+
this.numSignUps = 0;
|
|
21
|
+
/**
|
|
22
|
+
* Create a deep copy of the MaciState object.
|
|
23
|
+
* @returns A new instance of the MaciState object with the same properties.
|
|
24
|
+
*/
|
|
25
|
+
this.copy = () => {
|
|
26
|
+
const copied = new MaciState(this.stateTreeDepth);
|
|
27
|
+
copied.pubKeys = this.pubKeys.map((x) => x.copy());
|
|
28
|
+
copied.polls = new Map(Array.from(this.polls, ([key, value]) => [key, value.copy()]));
|
|
29
|
+
return copied;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Check if the MaciState object is equal to another MaciState object.
|
|
33
|
+
* @param m - The MaciState object to compare.
|
|
34
|
+
* @returns True if the two MaciState objects are equal, false otherwise.
|
|
35
|
+
*/
|
|
36
|
+
this.equals = (m) => {
|
|
37
|
+
const result = this.stateTreeDepth === m.stateTreeDepth &&
|
|
38
|
+
this.polls.size === m.polls.size &&
|
|
39
|
+
this.pubKeys.length === m.pubKeys.length;
|
|
40
|
+
if (!result) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
for (let i = 0; i < this.polls.size; i += 1) {
|
|
44
|
+
if (!this.polls.get(BigInt(i))?.equals(m.polls.get(BigInt(i)))) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
for (let i = 0; i < this.pubKeys.length; i += 1) {
|
|
49
|
+
if (!this.pubKeys[i].equals(m.pubKeys[i])) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return true;
|
|
54
|
+
};
|
|
55
|
+
this.stateTreeDepth = stateTreeDepth;
|
|
56
|
+
// we put a blank state leaf to prevent a DoS attack
|
|
57
|
+
this.pubKeys.push(domainobjs_1.padKey);
|
|
58
|
+
// we need to increase the number of signups by one given
|
|
59
|
+
// that we already added the blank leaf
|
|
60
|
+
this.numSignUps += 1;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Sign up a user with the given public key.
|
|
64
|
+
* @param pubKey - The public key of the user.
|
|
65
|
+
* @returns The index of the newly signed-up user in the state tree.
|
|
66
|
+
*/
|
|
67
|
+
signUp(pubKey) {
|
|
68
|
+
this.numSignUps += 1;
|
|
69
|
+
this.stateTree?.insert(pubKey.hash());
|
|
70
|
+
return this.pubKeys.push(pubKey.copy()) - 1;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Deploy a new poll with the given parameters.
|
|
74
|
+
* @param pollEndTimestamp - The Unix timestamp at which the poll ends.
|
|
75
|
+
* @param treeDepths - The depths of the tree.
|
|
76
|
+
* @param messageBatchSize - The batch size for processing messages.
|
|
77
|
+
* @param coordinatorKeypair - The keypair of the MACI round coordinator.
|
|
78
|
+
* @param voteOptions - The number of vote options for this poll.
|
|
79
|
+
* @returns The index of the newly deployed poll.
|
|
80
|
+
*/
|
|
81
|
+
deployPoll(pollEndTimestamp, treeDepths, messageBatchSize, coordinatorKeypair, voteOptions) {
|
|
82
|
+
const poll = new Poll_1.Poll(pollEndTimestamp, coordinatorKeypair, treeDepths, {
|
|
83
|
+
messageBatchSize,
|
|
84
|
+
tallyBatchSize: constants_1.STATE_TREE_ARITY ** treeDepths.intStateTreeDepth,
|
|
85
|
+
}, this, voteOptions);
|
|
86
|
+
this.polls.set(BigInt(this.polls.size), poll);
|
|
87
|
+
return BigInt(this.polls.size - 1);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Deploy a null poll.
|
|
91
|
+
*/
|
|
92
|
+
deployNullPoll() {
|
|
93
|
+
this.polls.set(BigInt(this.polls.size), null);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Serialize the MaciState object to a JSON object.
|
|
97
|
+
* @returns A JSON object representing the MaciState object.
|
|
98
|
+
*/
|
|
99
|
+
toJSON() {
|
|
100
|
+
return {
|
|
101
|
+
stateTreeDepth: this.stateTreeDepth,
|
|
102
|
+
polls: Array.from(this.polls.values()).map((poll) => poll.toJSON()),
|
|
103
|
+
pubKeys: this.pubKeys.map((pubKey) => pubKey.toJSON()),
|
|
104
|
+
pollBeingProcessed: Boolean(this.pollBeingProcessed),
|
|
105
|
+
currentPollBeingProcessed: this.currentPollBeingProcessed ? this.currentPollBeingProcessed.toString() : "",
|
|
106
|
+
numSignUps: this.numSignUps,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Create a new MaciState object from a JSON object.
|
|
111
|
+
* @param json - The JSON object representing the MaciState object.
|
|
112
|
+
* @returns A new instance of the MaciState object with the properties from the JSON object.
|
|
113
|
+
*/
|
|
114
|
+
static fromJSON(json) {
|
|
115
|
+
const maciState = new MaciState(json.stateTreeDepth);
|
|
116
|
+
// assign the json values to the new instance
|
|
117
|
+
maciState.pubKeys = json.pubKeys.map((pubKey) => domainobjs_1.PubKey.fromJSON(pubKey));
|
|
118
|
+
maciState.pollBeingProcessed = json.pollBeingProcessed;
|
|
119
|
+
maciState.currentPollBeingProcessed = BigInt(json.currentPollBeingProcessed);
|
|
120
|
+
maciState.numSignUps = json.numSignUps;
|
|
121
|
+
// re-generate the polls and set the maci state reference
|
|
122
|
+
maciState.polls = new Map(json.polls.map((jsonPoll, index) => [BigInt(index), Poll_1.Poll.fromJSON(jsonPoll, maciState)]));
|
|
123
|
+
return maciState;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.MaciState = MaciState;
|
|
127
|
+
//# sourceMappingURL=MaciState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaciState.js","sourceRoot":"","sources":["../../ts/MaciState.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { IncrementalQuinTree } from "@maci-protocol/crypto";
|
|
2
|
+
import { PCommand, Keypair, Ballot, PubKey, Message, StateLeaf } from "@maci-protocol/domainobjs";
|
|
3
|
+
import { LeanIMT } from "@zk-kit/lean-imt";
|
|
4
|
+
import type { TreeDepths, BatchSizes, IPoll, IJsonPoll, IProcessMessagesOutput, ITallyCircuitInputs, IProcessMessagesCircuitInputs, IPollJoiningCircuitInputs, IJoiningCircuitArgs } from "./index";
|
|
5
|
+
import type { MaciState } from "./MaciState";
|
|
6
|
+
import type { IJoinedCircuitArgs, IPollJoinedCircuitInputs } from "./utils/types";
|
|
7
|
+
/**
|
|
8
|
+
* A representation of the Poll contract.
|
|
9
|
+
*/
|
|
10
|
+
export declare class Poll implements IPoll {
|
|
11
|
+
coordinatorKeypair: Keypair;
|
|
12
|
+
treeDepths: TreeDepths;
|
|
13
|
+
batchSizes: BatchSizes;
|
|
14
|
+
voteOptions: bigint;
|
|
15
|
+
maxVoteOptions: number;
|
|
16
|
+
stateTreeDepth: number;
|
|
17
|
+
actualStateTreeDepth: number;
|
|
18
|
+
pollEndTimestamp: bigint;
|
|
19
|
+
ballots: Ballot[];
|
|
20
|
+
ballotTree?: IncrementalQuinTree;
|
|
21
|
+
messages: Message[];
|
|
22
|
+
commands: PCommand[];
|
|
23
|
+
encPubKeys: PubKey[];
|
|
24
|
+
stateCopied: boolean;
|
|
25
|
+
pubKeys: PubKey[];
|
|
26
|
+
stateTree?: LeanIMT;
|
|
27
|
+
numBatchesProcessed: number;
|
|
28
|
+
currentMessageBatchIndex: number;
|
|
29
|
+
maciStateRef: MaciState;
|
|
30
|
+
pollId: bigint;
|
|
31
|
+
sbSalts: Record<number | string, bigint>;
|
|
32
|
+
resultRootSalts: Record<number | string, bigint>;
|
|
33
|
+
preVOSpentVoiceCreditsRootSalts: Record<number | string, bigint>;
|
|
34
|
+
spentVoiceCreditSubtotalSalts: Record<number | string, bigint>;
|
|
35
|
+
tallyResult: bigint[];
|
|
36
|
+
perVOSpentVoiceCredits: bigint[];
|
|
37
|
+
numBatchesTallied: number;
|
|
38
|
+
totalSpentVoiceCredits: bigint;
|
|
39
|
+
emptyBallot: Ballot;
|
|
40
|
+
emptyBallotHash?: bigint;
|
|
41
|
+
chainHash: bigint;
|
|
42
|
+
batchHashes: bigint[];
|
|
43
|
+
pollStateLeaves: StateLeaf[];
|
|
44
|
+
pollStateTree?: IncrementalQuinTree;
|
|
45
|
+
pollNullifiers: Map<bigint, boolean>;
|
|
46
|
+
private numSignups;
|
|
47
|
+
/**
|
|
48
|
+
* Constructs a new Poll object.
|
|
49
|
+
* @param pollEndTimestamp - The Unix timestamp at which the poll ends.
|
|
50
|
+
* @param coordinatorKeypair - The keypair of the coordinator.
|
|
51
|
+
* @param treeDepths - The depths of the trees used in the poll.
|
|
52
|
+
* @param batchSizes - The sizes of the batches used in the poll.
|
|
53
|
+
* @param maciStateRef - The reference to the MACI state.
|
|
54
|
+
* @param pollId - The poll id
|
|
55
|
+
*/
|
|
56
|
+
constructor(pollEndTimestamp: bigint, coordinatorKeypair: Keypair, treeDepths: TreeDepths, batchSizes: BatchSizes, maciStateRef: MaciState, voteOptions: bigint);
|
|
57
|
+
/**
|
|
58
|
+
* Check if user has already joined the poll by checking if the nullifier is registered
|
|
59
|
+
*/
|
|
60
|
+
hasJoined: (nullifier: bigint) => boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Join the anonymous user to the Poll (to the tree)
|
|
63
|
+
* @param nullifier - Hashed private key used as nullifier
|
|
64
|
+
* @param pubKey - The poll public key.
|
|
65
|
+
* @param newVoiceCreditBalance - New voice credit balance of the user.
|
|
66
|
+
* @param timestamp - The timestamp of the sign-up.
|
|
67
|
+
* @returns The index of added state leaf
|
|
68
|
+
*/
|
|
69
|
+
joinPoll: (nullifier: bigint, pubKey: PubKey, newVoiceCreditBalance: bigint, timestamp: bigint) => number;
|
|
70
|
+
/**
|
|
71
|
+
* Update a Poll with data from MaciState.
|
|
72
|
+
* This is the step where we copy the state from the MaciState instance,
|
|
73
|
+
* and set the number of signups we have so far.
|
|
74
|
+
* @note It should be called to generate the state for poll joining with numSignups set as
|
|
75
|
+
* the number of signups in the MaciState. For message processing, you should set numSignups as
|
|
76
|
+
* the number of users who joined the poll.
|
|
77
|
+
*/
|
|
78
|
+
updatePoll: (numSignups: bigint) => void;
|
|
79
|
+
/**
|
|
80
|
+
* Process one message.
|
|
81
|
+
* @param message - The message to process.
|
|
82
|
+
* @param encPubKey - The public key associated with the encryption private key.
|
|
83
|
+
* @returns A number of variables which will be used in the zk-SNARK circuit.
|
|
84
|
+
*/
|
|
85
|
+
processMessage: (message: Message, encPubKey: PubKey, qv?: boolean) => IProcessMessagesOutput;
|
|
86
|
+
/**
|
|
87
|
+
* Inserts a Message and the corresponding public key used to generate the
|
|
88
|
+
* ECDH shared key which was used to encrypt said message.
|
|
89
|
+
* @param message - The message to insert
|
|
90
|
+
* @param encPubKey - The public key used to encrypt the message
|
|
91
|
+
*/
|
|
92
|
+
publishMessage: (message: Message, encPubKey: PubKey) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Updates message chain hash
|
|
95
|
+
* @param messageHash hash of message with encPubKey
|
|
96
|
+
*/
|
|
97
|
+
updateChainHash: (messageHash: bigint) => void;
|
|
98
|
+
/**
|
|
99
|
+
* Create circuit input for pollJoining
|
|
100
|
+
* @param args Poll joining circuit inputs
|
|
101
|
+
* @returns stringified circuit inputs
|
|
102
|
+
*/
|
|
103
|
+
joiningCircuitInputs: ({ maciPrivKey, stateLeafIndex, pollPubKey, }: IJoiningCircuitArgs) => IPollJoiningCircuitInputs;
|
|
104
|
+
/**
|
|
105
|
+
* Create circuit input for pollJoined
|
|
106
|
+
* @param args Poll joined circuit inputs
|
|
107
|
+
* @returns stringified circuit inputs
|
|
108
|
+
*/
|
|
109
|
+
joinedCircuitInputs: ({ maciPrivKey, stateLeafIndex, voiceCreditsBalance, joinTimestamp, }: IJoinedCircuitArgs) => IPollJoinedCircuitInputs;
|
|
110
|
+
/**
|
|
111
|
+
* Pad last unclosed batch
|
|
112
|
+
*/
|
|
113
|
+
padLastBatch: () => void;
|
|
114
|
+
/**
|
|
115
|
+
* This method checks if there are any unprocessed messages in the Poll instance.
|
|
116
|
+
* @returns Returns true if the number of processed batches is
|
|
117
|
+
* less than the total number of batches, false otherwise.
|
|
118
|
+
*/
|
|
119
|
+
hasUnprocessedMessages: () => boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Process _batchSize messages starting from the saved index. This
|
|
122
|
+
* function will process messages even if the number of messages is not an
|
|
123
|
+
* exact multiple of _batchSize. e.g. if there are 10 messages, index is
|
|
124
|
+
* 8, and _batchSize is 4, this function will only process the last two
|
|
125
|
+
* messages in this.messages, and finally update the zeroth state leaf.
|
|
126
|
+
* Note that this function will only process as many state leaves as there
|
|
127
|
+
* are ballots to prevent accidental inclusion of a new user after this
|
|
128
|
+
* poll has concluded.
|
|
129
|
+
* @param pollId The ID of the poll associated with the messages to
|
|
130
|
+
* process
|
|
131
|
+
* @param quiet - Whether to log errors or not
|
|
132
|
+
* @returns stringified circuit inputs
|
|
133
|
+
*/
|
|
134
|
+
processMessages: (pollId: bigint, qv?: boolean, quiet?: boolean) => IProcessMessagesCircuitInputs;
|
|
135
|
+
/**
|
|
136
|
+
* Generates partial circuit inputs for processing a batch of messages
|
|
137
|
+
* @param index - The index of the partial batch.
|
|
138
|
+
* @returns stringified partial circuit inputs
|
|
139
|
+
*/
|
|
140
|
+
private genProcessMessagesCircuitInputsPartial;
|
|
141
|
+
/**
|
|
142
|
+
* Process all messages. This function does not update the ballots or state
|
|
143
|
+
* leaves; rather, it copies and then updates them. This makes it possible
|
|
144
|
+
* to test the result of multiple processMessage() invocations.
|
|
145
|
+
* @returns The state leaves and ballots of the poll
|
|
146
|
+
*/
|
|
147
|
+
processAllMessages: () => {
|
|
148
|
+
stateLeaves: StateLeaf[];
|
|
149
|
+
ballots: Ballot[];
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Checks whether there are any untallied ballots.
|
|
153
|
+
* @returns Whether there are any untallied ballots
|
|
154
|
+
*/
|
|
155
|
+
hasUntalliedBallots: () => boolean;
|
|
156
|
+
/**
|
|
157
|
+
* This method tallies a ballots and updates the tally results.
|
|
158
|
+
* @returns the circuit inputs for the TallyVotes circuit.
|
|
159
|
+
*/
|
|
160
|
+
tallyVotes: () => ITallyCircuitInputs;
|
|
161
|
+
tallyVotesNonQv: () => ITallyCircuitInputs;
|
|
162
|
+
/**
|
|
163
|
+
* This method generates a commitment to the total spent voice credits.
|
|
164
|
+
*
|
|
165
|
+
* This is the hash of the total spent voice credits and a salt, computed as Poseidon([totalCredits, _salt]).
|
|
166
|
+
* @param salt - The salt used in the hash function.
|
|
167
|
+
* @param numBallotsToCount - The number of ballots to count for the calculation.
|
|
168
|
+
* @param useQuadraticVoting - Whether to use quadratic voting or not. Default is true.
|
|
169
|
+
* @returns Returns the hash of the total spent voice credits and a salt, computed as Poseidon([totalCredits, _salt]).
|
|
170
|
+
*/
|
|
171
|
+
private genSpentVoiceCreditSubtotalCommitment;
|
|
172
|
+
/**
|
|
173
|
+
* This method generates a commitment to the spent voice credits per vote option.
|
|
174
|
+
*
|
|
175
|
+
* This is the hash of the Merkle root of the spent voice credits per vote option and a salt, computed as Poseidon([root, _salt]).
|
|
176
|
+
* @param salt - The salt used in the hash function.
|
|
177
|
+
* @param numBallotsToCount - The number of ballots to count for the calculation.
|
|
178
|
+
* @param useQuadraticVoting - Whether to use quadratic voting or not. Default is true.
|
|
179
|
+
* @returns Returns the hash of the Merkle root of the spent voice credits per vote option and a salt, computed as Poseidon([root, _salt]).
|
|
180
|
+
*/
|
|
181
|
+
private genPerVOSpentVoiceCreditsCommitment;
|
|
182
|
+
/**
|
|
183
|
+
* Create a deep copy of the Poll object.
|
|
184
|
+
* @returns A new instance of the Poll object with the same properties.
|
|
185
|
+
*/
|
|
186
|
+
copy: () => Poll;
|
|
187
|
+
/**
|
|
188
|
+
* Check if the Poll object is equal to another Poll object.
|
|
189
|
+
* @param p - The Poll object to compare.
|
|
190
|
+
* @returns True if the two Poll objects are equal, false otherwise.
|
|
191
|
+
*/
|
|
192
|
+
equals: (p: Poll) => boolean;
|
|
193
|
+
/**
|
|
194
|
+
* Serialize the Poll object to a JSON object
|
|
195
|
+
* @returns a JSON object
|
|
196
|
+
*/
|
|
197
|
+
toJSON(): IJsonPoll;
|
|
198
|
+
/**
|
|
199
|
+
* Deserialize a json object into a Poll instance
|
|
200
|
+
* @param json the json object to deserialize
|
|
201
|
+
* @param maciState the reference to the MaciState Class
|
|
202
|
+
* @returns a new Poll instance
|
|
203
|
+
*/
|
|
204
|
+
static fromJSON(json: IJsonPoll, maciState: MaciState): Poll;
|
|
205
|
+
/**
|
|
206
|
+
* Set the coordinator's keypair
|
|
207
|
+
* @param serializedPrivateKey - the serialized private key
|
|
208
|
+
*/
|
|
209
|
+
setCoordinatorKeypair: (serializedPrivateKey: string) => void;
|
|
210
|
+
/**
|
|
211
|
+
* Set the number of signups to match the ones from the contract
|
|
212
|
+
* @param numSignups - the number of signups
|
|
213
|
+
*/
|
|
214
|
+
setNumSignups: (numSignups: bigint) => void;
|
|
215
|
+
/**
|
|
216
|
+
* Get the number of signups
|
|
217
|
+
* @returns The number of signups
|
|
218
|
+
*/
|
|
219
|
+
getNumSignups: () => bigint;
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=Poll.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Poll.d.ts","sourceRoot":"","sources":["../../ts/Poll.ts"],"names":[],"mappings":"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"}
|