Skip to content

Commit

Permalink
Add IPFS signature to polls and votes
Browse files Browse the repository at this point in the history
  • Loading branch information
ashutoshpw committed Mar 5, 2024
1 parent 2c219f7 commit 4e81a1f
Show file tree
Hide file tree
Showing 11 changed files with 9,722 additions and 498 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ yarn-error.log*
.vscode

.idea
.cosine
59 changes: 47 additions & 12 deletions components/choices/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ const express = require("express");
const dbo = require("../../db/conn");
const {
getInputFromSigPayload,
getTimestampFromPayloadBytes,
getIPFSProofFromPayload,
getUserTotalVotingPowerAtReferenceBlock,
} = require("../../utils");
const { default: BigNumber } = require("bignumber.js");
const { getPkhfromPk } = require("@taquito/utils");
const { uploadToIPFS } = require("../../services/ipfs.service");

// This help convert the id from string to ObjectId for the _id.
const ObjectId = require("mongodb").ObjectId;
Expand All @@ -33,13 +36,16 @@ const getChoiceById = async (req, response) => {
};

const updateChoiceById = async (req, response) => {
const { payloadBytes, publicKey } = req.body;
const { payloadBytes, publicKey, signature } = req.body;

let j = 0;
let i = 0;

try {
const values = getInputFromSigPayload(payloadBytes);

const payloadDate = getTimestampFromPayloadBytes(payloadBytes);

let db_connect = dbo.getDb("Lite");

const pollID = values[0].pollID;
Expand Down Expand Up @@ -105,7 +111,40 @@ const updateChoiceById = async (req, response) => {
if (total.eq(0)) {
throw new Error("No balance at proposal level");
}
const isVoted = await db_connect
.collection('Choices')
.find({
pollID: poll._id,
walletAddresses: { $elemMatch: { address: address } },
})
.toArray();

if (isVoted.length > 0) {
const oldVote = await db_connect.collection("Choices").findOne({
_id: ObjectId(isVoted[0].walletAddresses[0].choiceId),
});

const oldSignaturePayload = oldVote.walletAddresses[0].payloadBytes;
if (oldSignaturePayload) {
const oldSignatureDate =
getTimestampFromPayloadBytes(oldSignaturePayload);

if (payloadDate <= oldSignatureDate) {
throw new Error("Invalid Signature");
}
}
}

const cidLink = await uploadToIPFS(
getIPFSProofFromPayload(payloadBytes, signature)
);
if (!cidLink) {
throw new Error(
"Could not upload proof to IPFS, Vote was not registered. Please try again later"
);
}

// TODO: Optimize this Promise.all
await Promise.all(
values.map(async (value) => {
const { choiceId } = value;
Expand All @@ -114,19 +153,15 @@ const updateChoiceById = async (req, response) => {
address,
balanceAtReferenceBlock: total.toString(),
choiceId,
payloadBytes,
signature,
};

walletVote.cidLink = cidLink;

const choice = await db_connect
.collection("Choices")
.findOne({ _id: ObjectId(choiceId) });

const isVoted = await db_connect
.collection("Choices")
.find({
pollID: poll._id,
walletAddresses: { $elemMatch: { address: address } },
})
.toArray();
if (isVoted.length > 0) {
if (poll.votingStrategy === 0) {
const mongoClient = dbo.getClient();
Expand All @@ -137,9 +172,6 @@ const updateChoiceById = async (req, response) => {
walletAddresses: walletVote,
},
};
const oldVote = await db_connect.collection("Choices").findOne({
_id: ObjectId(isVoted[0].walletAddresses[0].choiceId),
});

let remove = {
$pull: {
Expand All @@ -152,6 +184,9 @@ const updateChoiceById = async (req, response) => {
try {
await session.withTransaction(async () => {
const coll1 = db_connect.collection("Choices");
// const coll2 = db_connect.collection("Polls");


// Important:: You must pass the session to the operations
await coll1.updateOne(
{ _id: ObjectId(oldVote._id) },
Expand Down
30 changes: 27 additions & 3 deletions components/polls/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ const {
getCurrentBlock,
getTotalSupplyAtCurrentBlock,
getUserTotalVotingPowerAtReferenceBlock,
getIPFSProofFromPayload,
} = require("../../utils");

const { uploadToIPFS } = require("../../services/ipfs.service");

const ObjectId = require("mongodb").ObjectId;

const getPollById = async (req, response) => {
Expand Down Expand Up @@ -49,7 +52,7 @@ const getPollsById = async (req, response) => {
};

const addPoll = async (req, response) => {
const { payloadBytes, publicKey } = req.body;
const { payloadBytes, publicKey, signature } = req.body;

try {
const values = getInputFromSigPayload(payloadBytes);
Expand Down Expand Up @@ -141,11 +144,29 @@ const addPoll = async (req, response) => {
_id: ObjectId(),
};
});

const choicesPoll = choicesData.map((element) => {
return element._id;
});

const pollExists = await db_connect
.collection("Polls")
.findOne({ payloadBytes });

if (pollExists) {
throw new Error("Invalid Signature, Poll already exists");
}

const cidLink = await uploadToIPFS(
getIPFSProofFromPayload(payloadBytes, signature)
);
if (!cidLink) {
throw new Error(
"Could not upload proof to IPFS, Vote was not registered. Please try again later"
);
}



let PollData = {
name,
description,
Expand All @@ -159,7 +180,10 @@ const addPoll = async (req, response) => {
choices: choicesPoll,
author,
votingStrategy,
isXTZ
isXTZ,
payloadBytes,
signature,
cidLink
};

let data = {
Expand Down
3 changes: 2 additions & 1 deletion config.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
ATLAS_URI=#YOUR_MONGODB_URI
PORT=#YOUR_NONDEFAULT_APP_PORT
PORT=#YOUR_NONDEFAULT_APP_PORT
NFT_STORAGE_KEY=XXXXXX #TokenFrom Nft.Storage
10 changes: 10 additions & 0 deletions config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require("dotenv").config({ path: "./config.env" });

const AppConfig = {
ServerPort: process.env.PORT || 5000,
IPFS: {
NFT_STORAGE_TOKEN: process.env.NFT_STORAGE_KEY,
}
}

module.exports = AppConfig
Loading

0 comments on commit 4e81a1f

Please sign in to comment.