mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-11-14 20:07:25 +00:00
get poll votes message
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
handleLastReference,
|
||||
handleNamesMessage,
|
||||
handlePollsMessage,
|
||||
handlePollVotesMessage,
|
||||
handlePrimaryNameMessage,
|
||||
handleProcessTransactionResponseMessage,
|
||||
handlePublicKeyMessage,
|
||||
@@ -36,7 +37,9 @@ import {
|
||||
createGetNamesForSalePayload,
|
||||
createGetNamesPayload,
|
||||
createGetOwnerGroupsPayload,
|
||||
createGetPollPayload,
|
||||
createGetPollsPayload,
|
||||
createGetPollVotesPayload,
|
||||
createGetPrimaryNamePayload,
|
||||
createGetPublickeyFromAddressPayload,
|
||||
createGetUnitFeePayload,
|
||||
@@ -119,6 +122,38 @@ export async function getPolls(
|
||||
return handlePollsMessage(res);
|
||||
}
|
||||
|
||||
export async function getPoll(pollName: string): Promise<any> {
|
||||
const client = getRandomClient();
|
||||
if (!client) throw new Error('No available peers');
|
||||
|
||||
const res: Buffer = await client.sendRequest(
|
||||
MessageType.GET_POLL,
|
||||
createGetPollPayload(pollName)
|
||||
);
|
||||
|
||||
const data = handlePollsMessage(res);
|
||||
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
return data[0];
|
||||
}
|
||||
|
||||
throw new Error('No poll data');
|
||||
}
|
||||
|
||||
export async function getPollVotes(
|
||||
pollName: string,
|
||||
onlyCounts: boolean
|
||||
): Promise<any> {
|
||||
const client = getRandomClient();
|
||||
if (!client) throw new Error('No available peers');
|
||||
|
||||
const res: Buffer = await client.sendRequest(
|
||||
MessageType.GET_POLL_VOTES,
|
||||
createGetPollVotesPayload(pollName, onlyCounts)
|
||||
);
|
||||
const data = handlePollVotesMessage(res);
|
||||
return data;
|
||||
}
|
||||
export async function getGroupMembers(
|
||||
groupId: number,
|
||||
onlyAdmins: boolean,
|
||||
|
||||
@@ -18,7 +18,9 @@ import {
|
||||
getNames,
|
||||
getNamesForSale,
|
||||
getOwnerGroups,
|
||||
getPoll,
|
||||
getPolls,
|
||||
getPollVotes,
|
||||
getPrimaryName,
|
||||
getPublickeyFromAddress,
|
||||
getSearchNames,
|
||||
@@ -369,6 +371,26 @@ export async function createHttpServer() {
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/polls/:pollName', async (req, res) => {
|
||||
try {
|
||||
const pollName = req.params.pollName;
|
||||
const pollInfo = await getPoll(pollName);
|
||||
res.json(pollInfo);
|
||||
} catch (err: any) {
|
||||
res.status(500).type('text').send(`Error: ${err.message}`);
|
||||
}
|
||||
});
|
||||
app.get('/polls/votes/:pollName', async (req, res) => {
|
||||
try {
|
||||
const pollName = req.params.pollName;
|
||||
const onlyCounts = req.query.onlyCounts === 'true';
|
||||
const pollInfo = await getPollVotes(pollName, Boolean(onlyCounts));
|
||||
res.json(pollInfo);
|
||||
} catch (err: any) {
|
||||
res.status(500).type('text').send(`Error: ${err.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
const server = createServer(app);
|
||||
const wss = new WebSocketServer({ noServer: true });
|
||||
|
||||
|
||||
@@ -391,6 +391,170 @@ export function handlePollsMessage(buffer) {
|
||||
return polls;
|
||||
}
|
||||
|
||||
// export function handlePollVotesMessage(buffer) {
|
||||
// let offset = 0;
|
||||
|
||||
// const { value: totalVotes, size: s1 } = readInt(buffer, offset);
|
||||
// offset += s1;
|
||||
|
||||
// const { value: totalWeight, size: s2 } = readInt(buffer, offset);
|
||||
// offset += s2;
|
||||
|
||||
// const { value: countSize, size: s3 } = readInt(buffer, offset);
|
||||
// offset += s3;
|
||||
|
||||
// const voteCounts = [];
|
||||
// for (let i = 0; i < countSize; i++) {
|
||||
// const { value: optionName, size: s4 } = readSizedString(buffer, offset);
|
||||
// offset += s4;
|
||||
|
||||
// const { value: voteCount, size: s5 } = readInt(buffer, offset);
|
||||
// offset += s5;
|
||||
|
||||
// voteCounts.push({ optionName, voteCount });
|
||||
// }
|
||||
|
||||
// const { value: weightSize, size: s6 } = readInt(buffer, offset);
|
||||
// offset += s6;
|
||||
|
||||
// const voteWeights = [];
|
||||
// for (let i = 0; i < weightSize; i++) {
|
||||
// const { value: optionName, size: s7 } = readSizedString(buffer, offset);
|
||||
// offset += s7;
|
||||
|
||||
// const { value: voteWeight, size: s8 } = readInt(buffer, offset);
|
||||
// offset += s8;
|
||||
|
||||
// voteWeights.push({ optionName, voteWeight });
|
||||
// }
|
||||
|
||||
// const { value: hasVotes, size: s9 } = readInt(buffer, offset);
|
||||
// offset += s9;
|
||||
|
||||
// let votes = null;
|
||||
// if (hasVotes === 1) {
|
||||
// const { value: votesCount, size: s10 } = readInt(buffer, offset);
|
||||
// offset += s10;
|
||||
|
||||
// votes = [];
|
||||
// for (let i = 0; i < votesCount; i++) {
|
||||
// const voterPublicKeyBytes = buffer.subarray(offset, offset + 32);
|
||||
// const voterPublicKey = bs58.encode(voterPublicKeyBytes);
|
||||
// offset += 32;
|
||||
|
||||
// const { value: optionIndex, size: s11 } = readInt(buffer, offset);
|
||||
// offset += s11;
|
||||
|
||||
// votes.push({ voterPublicKey, optionIndex });
|
||||
// }
|
||||
// }
|
||||
|
||||
// return {
|
||||
// totalVotes,
|
||||
// totalWeight,
|
||||
// voteCounts,
|
||||
// voteWeights,
|
||||
// votes,
|
||||
// };
|
||||
// }
|
||||
|
||||
// Debugger version of handlePollVotesMessage
|
||||
|
||||
export function handlePollVotesMessage(buffer) {
|
||||
const dataView = new DataView(
|
||||
buffer.buffer,
|
||||
buffer.byteOffset,
|
||||
buffer.byteLength
|
||||
);
|
||||
let offset = 0;
|
||||
|
||||
const readInt = () => {
|
||||
const value = dataView.getInt32(offset, false); // big-endian
|
||||
offset += 4;
|
||||
return value;
|
||||
};
|
||||
|
||||
const readSizedString = () => {
|
||||
const length = readInt();
|
||||
if (length === 0) return '';
|
||||
const strBytes = buffer.subarray(offset, offset + length);
|
||||
offset += length;
|
||||
return new TextDecoder().decode(strBytes);
|
||||
};
|
||||
|
||||
const readBytes = (length) => {
|
||||
const bytes = buffer.subarray(offset, offset + length);
|
||||
offset += length;
|
||||
return bytes;
|
||||
};
|
||||
|
||||
const log = (...args) => console.log('[Offset:', offset, ']', ...args);
|
||||
|
||||
// hasVotes flag
|
||||
const hasVotes = readInt();
|
||||
log('hasVotes:', hasVotes);
|
||||
|
||||
let votes = null;
|
||||
if (hasVotes === 1) {
|
||||
const votesCount = readInt();
|
||||
log('votesCount:', votesCount);
|
||||
|
||||
votes = [];
|
||||
for (let i = 0; i < votesCount; i++) {
|
||||
const pollName = readSizedString();
|
||||
log(`vote[${i}] pollName:`, pollName);
|
||||
|
||||
const voterPublicKeyBytes = readBytes(32);
|
||||
const voterPublicKey = bs58.encode(voterPublicKeyBytes);
|
||||
log(`vote[${i}] voterPublicKey:`, voterPublicKey);
|
||||
|
||||
const optionIndex = readInt();
|
||||
log(`vote[${i}] optionIndex:`, optionIndex);
|
||||
|
||||
votes.push({ pollName, voterPublicKey, optionIndex });
|
||||
}
|
||||
}
|
||||
|
||||
const totalVotes = readInt();
|
||||
log('totalVotes:', totalVotes);
|
||||
|
||||
const totalWeight = readInt();
|
||||
log('totalWeight:', totalWeight);
|
||||
|
||||
const voteCountsSize = readInt();
|
||||
log('voteCounts size:', voteCountsSize);
|
||||
|
||||
const voteCounts = [];
|
||||
for (let i = 0; i < voteCountsSize; i++) {
|
||||
const optionName = readSizedString();
|
||||
const voteCount = readInt();
|
||||
log(`voteCount[${i}] optionName:`, optionName, 'count:', voteCount);
|
||||
voteCounts.push({ optionName, voteCount });
|
||||
}
|
||||
|
||||
const voteWeightsSize = readInt();
|
||||
log('voteWeights size:', voteWeightsSize);
|
||||
|
||||
const voteWeights = [];
|
||||
for (let i = 0; i < voteWeightsSize; i++) {
|
||||
const optionName = readSizedString();
|
||||
const voteWeight = readInt();
|
||||
log(`voteWeight[${i}] optionName:`, optionName, 'weight:', voteWeight);
|
||||
voteWeights.push({ optionName, voteWeight });
|
||||
}
|
||||
|
||||
log('Final offset:', offset, '/', buffer.length);
|
||||
|
||||
return {
|
||||
hasVotes: hasVotes === 1,
|
||||
votes,
|
||||
totalVotes,
|
||||
totalWeight,
|
||||
voteCounts,
|
||||
voteWeights,
|
||||
};
|
||||
}
|
||||
|
||||
export function handleUnitFee(payload: Buffer): bigint {
|
||||
if (payload.length !== 8) {
|
||||
throw new Error(
|
||||
|
||||
@@ -52,4 +52,7 @@ export enum MessageType {
|
||||
|
||||
POLLS = 326,
|
||||
GET_POLLS = 327,
|
||||
GET_POLL = 328,
|
||||
POLL_VOTES = 329,
|
||||
GET_POLL_VOTES = 330,
|
||||
}
|
||||
|
||||
@@ -191,6 +191,33 @@ export function createGetPollsPayload(
|
||||
return Buffer.concat([limitBuffer, offsetBuffer, reverseBuffer]);
|
||||
}
|
||||
|
||||
export function createGetPollPayload(pollName: string): Buffer {
|
||||
const pollNameBuffer = Buffer.from(pollName, 'utf-8');
|
||||
const pollNameLength = Buffer.alloc(4);
|
||||
pollNameLength.writeInt32BE(pollNameBuffer.length);
|
||||
|
||||
const payloadParts = [pollNameLength, pollNameBuffer];
|
||||
|
||||
return Buffer.concat(payloadParts);
|
||||
}
|
||||
|
||||
export function createGetPollVotesPayload(pollName, onlyCounts) {
|
||||
const pollNameBuffer = Buffer.from(pollName, 'utf-8');
|
||||
const pollNameLengthBuffer = Buffer.alloc(4);
|
||||
pollNameLengthBuffer.writeInt32BE(pollNameBuffer.length);
|
||||
|
||||
const onlyCountsBuffer = Buffer.alloc(4);
|
||||
onlyCountsBuffer.writeInt32BE(onlyCounts ? 1 : 0);
|
||||
|
||||
const buffer = Buffer.concat([
|
||||
pollNameLengthBuffer,
|
||||
pollNameBuffer,
|
||||
onlyCountsBuffer,
|
||||
]);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
export function createGetGroupMembersPayload(
|
||||
groupId: number,
|
||||
onlyAdmins: boolean,
|
||||
|
||||
Reference in New Issue
Block a user