diff --git a/package.json b/package.json index 3e257448..e2dd54bf 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "@ethersproject/units": "^5.7.0", "@ethersproject/wallet": "^5.7.0", "@size-limit/file": "^8.2.4", - "@vocdoni/proto": "1.15.4", + "@vocdoni/proto": "1.15.5", "axios": "0.27.2", "blake2b": "^2.1.4", "iso-language-codes": "^1.1.0", diff --git a/src/api/api.ts b/src/api/api.ts index 1a4940c1..23547773 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -50,14 +50,14 @@ export abstract class API { private static isVochainError(error: string): never { switch (true) { - case error.includes('starts at height') && error.includes('current height is'): + case error.includes('starts at') && error.includes('current'): throw new ErrElectionNotStarted(error); - case error.includes('finished at height') && error.includes('current height is'): + case error.includes('finished at') && error.includes('current'): throw new ErrElectionFinished(error); case error.includes('current state: ENDED'): throw new ErrElectionFinished(error); default: - throw error; + throw new ErrAPI(error); } } diff --git a/src/api/election.ts b/src/api/election.ts index 4e24d5f3..70e5098c 100644 --- a/src/api/election.ts +++ b/src/api/election.ts @@ -511,7 +511,7 @@ export abstract class ElectionAPI extends API { * * @param {string} url API endpoint URL * @param {number} maxCensusSize - * @param {number} electionBlocks + * @param {number} electionDuration * @param {boolean} encryptedVotes * @param {boolean} anonymousVotes * @param {number} maxVoteOverwrite @@ -520,7 +520,7 @@ export abstract class ElectionAPI extends API { public static price( url: string, maxCensusSize: number, - electionBlocks: number, + electionDuration: number, encryptedVotes: boolean, anonymousVotes: boolean, maxVoteOverwrite: number @@ -528,7 +528,7 @@ export abstract class ElectionAPI extends API { return axios .post(url + ElectionAPIMethods.PRICE, { maxCensusSize, - electionBlocks, + electionDuration, encryptedVotes, anonymousVotes, maxVoteOverwrite, diff --git a/src/client.ts b/src/client.ts index cdff80ff..bbbd1a9d 100644 --- a/src/client.ts +++ b/src/client.ts @@ -561,26 +561,7 @@ export class VocdoniSDKClient { key: ElectionCreationSteps.GET_DATA_PIN, }; - const blocks = { - actual: chainData.height, - start: 0, - end: 0, - }; - if (election.startDate) { - blocks.start = await this.chainService.dateToBlock(election.startDate); - } - blocks.end = await this.chainService.dateToBlock(election.endDate); - yield { - key: ElectionCreationSteps.ESTIMATE_BLOCK_TIMES, - }; - - const electionTxData = ElectionCore.generateNewElectionTransaction( - election, - cid, - blocks, - account.address, - account.nonce - ); + const electionTxData = ElectionCore.generateNewElectionTransaction(election, cid, account.address, account.nonce); yield { key: ElectionCreationSteps.GENERATE_TX, }; diff --git a/src/core/election.ts b/src/core/election.ts index 55cd177f..c12a269c 100644 --- a/src/core/election.ts +++ b/src/core/election.ts @@ -11,11 +11,11 @@ import { AllElectionStatus, CensusType, ElectionStatus, UnpublishedElection } fr import { TransactionCore } from './transaction'; import { Buffer } from 'buffer'; import { strip0x } from '../util/common'; -import { ChainCosts, ChainData } from '../services'; +import { ChainCosts } from '../services'; import { TxMessage } from '../util/constants'; export abstract class ElectionCore extends TransactionCore { - private static readonly VOCHAIN_BLOCK_TIME_IN_SECONDS = 12; + private static readonly VOCHAIN_BLOCK_TIME_IN_SECONDS = 10; /** * Cannot be constructed. @@ -71,11 +71,10 @@ export abstract class ElectionCore extends TransactionCore { public static generateNewElectionTransaction( election: UnpublishedElection, cid: string, - blocks: { actual: number; start: number; end: number }, address: string, nonce: number ): { tx: Uint8Array; metadata: string; message: string } { - const txData = this.prepareElectionData(election, cid, blocks, address, nonce); + const txData = this.prepareElectionData(election, cid, address, nonce); const newProcess = NewProcessTx.fromPartial({ txtype: TxType.NEW_PROCESS, @@ -93,18 +92,23 @@ export abstract class ElectionCore extends TransactionCore { private static prepareElectionData( election: UnpublishedElection, cid: string, - blocks: { actual: number; start: number; end: number }, address: string, nonce: number ): { metadata: string; electionData: object } { + let startTime = election.startDate ? Math.floor(election.startDate.getTime() / 1000) : 0; + // If the start date is less than the current time plus the block time, set it to begin immediately + // This is to prevent the transaction to be rejected by the node + if (startTime !== 0 && startTime < Math.floor(Date.now() / 1000) + this.VOCHAIN_BLOCK_TIME_IN_SECONDS * 5) { + startTime = 0; + } return { metadata: Buffer.from(JSON.stringify(election.generateMetadata()), 'utf8').toString('base64'), electionData: { nonce: nonce, process: { entityId: Uint8Array.from(Buffer.from(address, 'hex')), - startBlock: election.startDate ? blocks.start : 0, - blockCount: blocks.end - (election.startDate ? blocks.start : blocks.actual), + startTime, + duration: election.duration, censusRoot: Uint8Array.from(Buffer.from(election.census.censusId, 'hex')), censusURI: election.census.censusURI, status: ProcessStatus.READY, @@ -139,19 +143,12 @@ export abstract class ElectionCore extends TransactionCore { } } - public static estimateElectionBlocks(election: UnpublishedElection, chainData: ChainData): number { - return ( - this.estimateBlockAtDateTime(election.endDate, chainData) - - this.estimateBlockAtDateTime(election.startDate ?? new Date(), chainData) - ); - } - - public static estimateElectionCost(election: UnpublishedElection, costs: ChainCosts, chainData: ChainData): number { + public static estimateElectionCost(election: UnpublishedElection, costs: ChainCosts): number { if (!election.maxCensusSize) { throw new Error('Could not estimate cost because maxCensusSize is not set'); } - const electionBlocks = this.estimateElectionBlocks(election, chainData); + const electionBlocks = Math.floor(election.duration / this.VOCHAIN_BLOCK_TIME_IN_SECONDS); if (electionBlocks <= 0) { throw new Error('Could not estimate cost because of negative election blocks size'); @@ -188,179 +185,4 @@ export abstract class ElectionCore extends TransactionCore { return costs.basePrice + sizePrice + durationPrice + encryptedPrice + anonymousPrice + overwritePrice; } - - /** - * Returns the DateTime at which the given block number is expected to be mined - * - * @param blockNumber The desired block number - * @param chainData The block status information from the chain to use for the estimation - */ - // @ts-ignore - private static estimateDateAtBlock(blockNumber: number, chainData: ChainData): Date { - if (!blockNumber) return null; - - const blocksPerM = 60 / this.VOCHAIN_BLOCK_TIME_IN_SECONDS; - const blocksPer10m = 10 * blocksPerM; - const blocksPerH = blocksPerM * 60; - const blocksPer6h = 6 * blocksPerH; - const blocksPerDay = 24 * blocksPerH; - - // Diff between the last mined block and the given one - const blockDiff = Math.abs(blockNumber - chainData.height); - let averageBlockTime = this.VOCHAIN_BLOCK_TIME_IN_SECONDS * 1000; - let weightA: number, weightB: number; - - // chainData.blockTime => [1m, 10m, 1h, 6h, 24h] - if (blockDiff > blocksPerDay) { - if (chainData.blockTime[4] > 0) averageBlockTime = chainData.blockTime[4]; - else if (chainData.blockTime[3] > 0) averageBlockTime = chainData.blockTime[3]; - else if (chainData.blockTime[2] > 0) averageBlockTime = chainData.blockTime[2]; - else if (chainData.blockTime[1] > 0) averageBlockTime = chainData.blockTime[1]; - else if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } else if (blockDiff > blocksPer6h) { - // blocksPer6h <= blockDiff < blocksPerDay - const pivot = (blockDiff - blocksPer6h) / blocksPerH; - weightB = pivot / (24 - 6); // 0..1 - weightA = 1 - weightB; - - if (chainData.blockTime[4] > 0 && chainData.blockTime[3] > 0) { - averageBlockTime = weightA * chainData.blockTime[3] + weightB * chainData.blockTime[4]; - } else if (chainData.blockTime[3] > 0) averageBlockTime = chainData.blockTime[3]; - else if (chainData.blockTime[2] > 0) averageBlockTime = chainData.blockTime[2]; - else if (chainData.blockTime[1] > 0) averageBlockTime = chainData.blockTime[1]; - else if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } else if (blockDiff > blocksPerH) { - // blocksPerH <= blockDiff < blocksPer6h - const pivot = (blockDiff - blocksPerH) / blocksPerH; - weightB = pivot / (6 - 1); // 0..1 - weightA = 1 - weightB; - - if (chainData.blockTime[3] > 0 && chainData.blockTime[2] > 0) { - averageBlockTime = weightA * chainData.blockTime[2] + weightB * chainData.blockTime[3]; - } else if (chainData.blockTime[2] > 0) averageBlockTime = chainData.blockTime[2]; - else if (chainData.blockTime[1] > 0) averageBlockTime = chainData.blockTime[1]; - else if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } else if (blockDiff > blocksPer10m) { - // blocksPer10m <= blockDiff < blocksPerH - const pivot = (blockDiff - blocksPer10m) / blocksPerM; - weightB = pivot / (60 - 10); // 0..1 - weightA = 1 - weightB; - - if (chainData.blockTime[2] > 0 && chainData.blockTime[1] > 0) { - averageBlockTime = weightA * chainData.blockTime[1] + weightB * chainData.blockTime[2]; - } else if (chainData.blockTime[1] > 0) averageBlockTime = chainData.blockTime[1]; - else if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } else if (blockDiff > blocksPerM) { - // blocksPerM <= blockDiff < blocksPer10m - const pivot = (blockDiff - blocksPerM) / blocksPerM; - weightB = pivot / (10 - 1); // 0..1 - weightA = 1 - weightB; - - if (chainData.blockTime[1] > 0 && chainData.blockTime[0] > 0) { - averageBlockTime = weightA * chainData.blockTime[0] + weightB * chainData.blockTime[1]; - } else if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } else { - if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } - - const targetTimestamp = chainData.blockTimestamp * 1000 + (blockNumber - chainData.height) * averageBlockTime; - return new Date(targetTimestamp); - } - - /** - * Returns the block number that is expected to be current at the given date and time - * - * @param dateTime The desired date time - * @param chainData The block status information from the chain to use for the estimation - */ - private static estimateBlockAtDateTime(dateTime: Date, chainData: ChainData): number { - if (typeof dateTime == 'number') dateTime = new Date(dateTime); - else if (!(dateTime instanceof Date)) return null; - - const outliers = (arr: number[]): number[] => { - const values = arr.concat(); - values.sort((a, b) => a - b); - - const q1 = values[Math.floor(values.length / 4)]; - const q3 = values[Math.ceil(values.length * (3 / 4))]; - const iqr = q3 - q1; - const maxValue = q3 + iqr * 1.5; - const minValue = q1 - iqr * 1.5; - - return values.filter((x) => x <= maxValue && x >= minValue); - }; - - chainData.blockTime = chainData.blockTime.map((part) => { - return outliers(chainData.blockTime).includes(part) ? part : 0; - }); - - let averageBlockTime = this.VOCHAIN_BLOCK_TIME_IN_SECONDS * 1000; - let weightA: number, weightB: number; - - // Diff between the last mined block and the given date - const dateDiff = Math.abs(dateTime.getTime() - chainData.blockTimestamp * 1000); - - // chainData.blockTime => [1m, 10m, 1h, 6h, 24h] - - if (dateDiff >= 1000 * 60 * 60 * 24) { - if (chainData.blockTime[4] > 0) averageBlockTime = chainData.blockTime[4]; - else if (chainData.blockTime[3] > 0) averageBlockTime = chainData.blockTime[3]; - else if (chainData.blockTime[2] > 0) averageBlockTime = chainData.blockTime[2]; - else if (chainData.blockTime[1] > 0) averageBlockTime = chainData.blockTime[1]; - else if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } else if (dateDiff >= 1000 * 60 * 60 * 6) { - // 1000 * 60 * 60 * 6 <= dateDiff < 1000 * 60 * 60 * 24 - if (chainData.blockTime[4] > 0 && chainData.blockTime[3] > 0) { - const pivot = (dateDiff - 1000 * 60 * 60 * 6) / (1000 * 60 * 60); - weightB = pivot / (24 - 6); // 0..1 - weightA = 1 - weightB; - - averageBlockTime = weightA * chainData.blockTime[3] + weightB * chainData.blockTime[4]; - } else if (chainData.blockTime[3] > 0) averageBlockTime = chainData.blockTime[3]; - else if (chainData.blockTime[2] > 0) averageBlockTime = chainData.blockTime[2]; - else if (chainData.blockTime[1] > 0) averageBlockTime = chainData.blockTime[1]; - else if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } else if (dateDiff >= 1000 * 60 * 60) { - // 1000 * 60 * 60 <= dateDiff < 1000 * 60 * 60 * 6 - if (chainData.blockTime[3] > 0 && chainData.blockTime[2] > 0) { - const pivot = (dateDiff - 1000 * 60 * 60) / (1000 * 60 * 60); - weightB = pivot / (6 - 1); // 0..1 - weightA = 1 - weightB; - - averageBlockTime = weightA * chainData.blockTime[2] + weightB * chainData.blockTime[3]; - } else if (chainData.blockTime[2] > 0) averageBlockTime = chainData.blockTime[2]; - else if (chainData.blockTime[1] > 0) averageBlockTime = chainData.blockTime[1]; - else if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } else if (dateDiff >= 1000 * 60 * 10) { - // 1000 * 60 * 10 <= dateDiff < 1000 * 60 * 60 - if (chainData.blockTime[2] > 0 && chainData.blockTime[1] > 0) { - const pivot = (dateDiff - 1000 * 60 * 10) / (1000 * 60); - weightB = pivot / (60 - 10); // 0..1 - weightA = 1 - weightB; - - averageBlockTime = weightA * chainData.blockTime[1] + weightB * chainData.blockTime[2]; - } else if (chainData.blockTime[1] > 0) averageBlockTime = chainData.blockTime[1]; - else if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } else if (dateDiff >= 1000 * 60) { - // 1000 * 60 <= dateDiff < 1000 * 60 * 6 - const pivot = (dateDiff - 1000 * 60) / (1000 * 60); - weightB = pivot / (10 - 1); // 0..1 - weightA = 1 - weightB; - - if (chainData.blockTime[1] > 0 && chainData.blockTime[0] > 0) { - averageBlockTime = weightA * chainData.blockTime[0] + weightB * chainData.blockTime[1]; - } else if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } else { - if (chainData.blockTime[0] > 0) averageBlockTime = chainData.blockTime[0]; - } - - const estimatedBlockDiff = dateDiff / averageBlockTime; - const estimatedBlock = - dateTime.getTime() < chainData.blockTimestamp * 1000 - ? chainData.height - Math.ceil(estimatedBlockDiff) - : chainData.height + Math.floor(estimatedBlockDiff); - - if (estimatedBlock < 0) return 0; - return estimatedBlock; - } } diff --git a/src/services/election.ts b/src/services/election.ts index 39602295..beec7f1e 100644 --- a/src/services/election.ts +++ b/src/services/election.ts @@ -41,7 +41,6 @@ export enum ElectionCreationSteps { CENSUS_CREATED = 'census-created', GET_ACCOUNT_DATA = 'get-account-data', GET_DATA_PIN = 'get-data-pin', - ESTIMATE_BLOCK_TIMES = 'estimate-block-times', GENERATE_TX = 'generate-tx', SIGN_TX = 'sign-tx', CREATING = 'creating', @@ -53,7 +52,6 @@ export type ElectionCreationStepValue = | { key: ElectionCreationSteps.CENSUS_CREATED } | { key: ElectionCreationSteps.GET_ACCOUNT_DATA } | { key: ElectionCreationSteps.GET_DATA_PIN } - | { key: ElectionCreationSteps.ESTIMATE_BLOCK_TIMES } | { key: ElectionCreationSteps.GENERATE_TX } | { key: ElectionCreationSteps.SIGN_TX } | { key: ElectionCreationSteps.CREATING; txHash: string } @@ -326,8 +324,9 @@ export class ElectionService extends Service implements ElectionServicePropertie */ estimateElectionCost(election: UnpublishedElection): Promise { invariant(this.chainService, 'No chain service set'); - return Promise.all([this.chainService.fetchChainCosts(), this.chainService.fetchChainData()]) - .then(([chainCosts, chainData]) => ElectionCore.estimateElectionCost(election, chainCosts, chainData)) + return this.chainService + .fetchChainCosts() + .then((chainCosts) => ElectionCore.estimateElectionCost(election, chainCosts)) .then((cost) => Math.trunc(cost)); } @@ -337,20 +336,14 @@ export class ElectionService extends Service implements ElectionServicePropertie * @returns {Promise} The cost in tokens. */ calculateElectionCost(election: UnpublishedElection): Promise { - invariant(this.chainService, 'No chain service set'); invariant(this.url, 'No URL set'); - return this.chainService - .fetchChainData() - .then((chainData) => - ElectionAPI.price( - this.url, - election.maxCensusSize, - ElectionCore.estimateElectionBlocks(election, chainData), - election.electionType.secretUntilTheEnd, - election.electionType.anonymous, - election.voteType.maxVoteOverwrites - ) - ) - .then((cost) => cost.price); + return ElectionAPI.price( + this.url, + election.maxCensusSize, + election.duration, + election.electionType.secretUntilTheEnd, + election.electionType.anonymous, + election.voteType.maxVoteOverwrites + ).then((cost) => cost.price); } } diff --git a/src/types/election/unpublished.ts b/src/types/election/unpublished.ts index 1a46aa2e..19017d78 100644 --- a/src/types/election/unpublished.ts +++ b/src/types/election/unpublished.ts @@ -135,6 +135,12 @@ export class UnpublishedElection extends Election { return { maxCount, maxValue, maxVoteOverwrites, maxTotalCost, costExponent }; } + get duration(): number { + return this.startDate + ? Math.floor((this.endDate.getTime() - this.startDate.getTime()) / 1000) + : Math.floor((this.endDate.getTime() - Date.now()) / 1000); + } + public generateEnvelopeType(): object { const serial = false; // TODO const anonymous = this.electionType.anonymous; diff --git a/test/api/vote.test.ts b/test/api/vote.test.ts index fc5ffdc5..15710cd4 100644 --- a/test/api/vote.test.ts +++ b/test/api/vote.test.ts @@ -1,81 +1,80 @@ -// @TODO: Fix this test when timestamps are ready -// import { -// Election, -// ElectionStatus, -// EnvOptions, -// ErrElectionFinished, -// ErrElectionNotStarted, -// PlainCensus, -// VocdoniSDKClient, -// Vote, -// } from '../../src'; -// // @ts-ignore -// import { URL, setFaucetURL } from './util/client.params'; -// import { Wallet } from '@ethersproject/wallet'; -// -// let client: VocdoniSDKClient; -// let wallet: Wallet; -// -// beforeEach(async () => { -// wallet = Wallet.createRandom(); -// client = new VocdoniSDKClient({ -// env: EnvOptions.DEV, -// api_url: URL, -// wallet, -// }); -// client = setFaucetURL(client); -// }); -// -// const createElection = (census, electionType?, voteType?) => { -// const election = Election.from({ -// title: 'SDK Testing - Title', -// description: 'SDK Testing - Description', -// startDate: new Date().getTime() + 24000, -// endDate: new Date().getTime() + 36000, -// census, -// electionType: electionType ?? null, -// voteType: voteType ?? null, -// }); -// -// election.addQuestion('This is a title', 'This is a description', [ -// { -// title: 'Option 1', -// value: 0, -// }, -// { -// title: 'Option 2', -// value: 1, -// }, -// ]); -// -// return election; -// }; -// +import { + Election, + ElectionStatus, + EnvOptions, + ErrElectionFinished, + ErrElectionNotStarted, + PlainCensus, + VocdoniSDKClient, + Vote, +} from '../../src'; +// @ts-ignore +import { URL, setFaucetURL } from './util/client.params'; +import { Wallet } from '@ethersproject/wallet'; + +let client: VocdoniSDKClient; +let wallet: Wallet; + +beforeEach(async () => { + wallet = Wallet.createRandom(); + client = new VocdoniSDKClient({ + env: EnvOptions.DEV, + api_url: URL, + wallet, + }); + client = setFaucetURL(client); +}); + +const createElection = (census, electionType?, voteType?) => { + const election = Election.from({ + title: 'SDK Testing - Title', + description: 'SDK Testing - Description', + startDate: new Date().getTime() + 80 * 1000, + endDate: new Date().getTime() + 80 * 1000 * 2, + census, + electionType: electionType ?? null, + voteType: voteType ?? null, + }); + + election.addQuestion('This is a title', 'This is a description', [ + { + title: 'Option 1', + value: 0, + }, + { + title: 'Option 2', + value: 1, + }, + ]); + + return election; +}; + describe('Vote API tests', () => { it('should throw trying to vote when election has not started and when is already finished', async () => { - // const voter = Wallet.createRandom(); - // const census = new PlainCensus(); - // census.add(await voter.getAddress()); - // - // const election = createElection(census); - // await client.createAccount(); - // const electionId = await client.createElection(election); - // - // client.wallet = voter; - // client.setElectionId(electionId); - // const vote = new Vote([1]); - // - // await expect(async () => { - // await client.submitVote(vote); - // }).rejects.toThrow(ErrElectionNotStarted); - // - // let publishedElection; - // do { - // publishedElection = await client.fetchElection(electionId); - // } while (publishedElection.status !== ElectionStatus.ENDED); - // - // await expect(async () => { - // await client.submitVote(vote); - // }).rejects.toThrow(ErrElectionFinished); - }, 120000); + const voter = Wallet.createRandom(); + const census = new PlainCensus(); + census.add(await voter.getAddress()); + + const election = createElection(census); + await client.createAccount(); + const electionId = await client.createElection(election); + + client.wallet = voter; + client.setElectionId(electionId); + const vote = new Vote([1]); + + await expect(async () => { + await client.submitVote(vote); + }).rejects.toThrow(ErrElectionNotStarted); + + let publishedElection; + do { + publishedElection = await client.fetchElection(electionId); + } while (publishedElection.status !== ElectionStatus.ENDED); + + await expect(async () => { + await client.submitVote(vote); + }).rejects.toThrow(ErrElectionFinished); + }, 280000); }); diff --git a/test/integration/csp.test.ts b/test/integration/csp.test.ts index 79d1bdd6..14511364 100644 --- a/test/integration/csp.test.ts +++ b/test/integration/csp.test.ts @@ -25,7 +25,7 @@ describe('CSP tests', () => { description: 'Election description', header: 'https://source.unsplash.com/random', streamUri: 'https://source.unsplash.com/random', - endDate: new Date().getTime() + 10000000, + endDate: new Date().getTime() + 60 * 60 * 1000, census, maxCensusSize: numVotes, }); diff --git a/test/integration/election.test.ts b/test/integration/election.test.ts index 59b517ce..3b1d90df 100644 --- a/test/integration/election.test.ts +++ b/test/integration/election.test.ts @@ -34,7 +34,7 @@ const createElection = (census, electionType?, voteType?, maxCensusSize?) => { const election = Election.from({ title: 'SDK Testing - Title', description: 'SDK Testing - Description', - endDate: new Date().getTime() + 10000000, + endDate: new Date().getTime() + 60 * 60 * 1000, census, maxCensusSize, electionType: electionType ?? null, @@ -599,7 +599,7 @@ describe('Election integration tests', () => { const election = MultiChoiceElection.from({ title: 'SDK Testing - Title', description: 'SDK Testing - Description', - endDate: new Date().getTime() + 10000000, + endDate: new Date().getTime() + 60 * 60 * 1000, census, maxNumberOfChoices: 3, canAbstain: true, diff --git a/test/integration/zk.test.ts b/test/integration/zk.test.ts index c6457b69..6b54c9cb 100644 --- a/test/integration/zk.test.ts +++ b/test/integration/zk.test.ts @@ -31,7 +31,7 @@ const createElection = (census, electionType?, voteType?, maxCensusSize?) => { const election = Election.from({ title: 'SDK Testing - Title', description: 'SDK Testing - Description', - endDate: new Date().getTime() + 10000000, + endDate: new Date().getTime() + 60 * 60 * 1000, census, maxCensusSize, electionType: electionType ?? null,