Skip to content

Commit

Permalink
shows proper shares from zig server; assigns share per connected user…
Browse files Browse the repository at this point in the history
… (needs secret reconstruction with assigned shares still)
  • Loading branch information
diegoandino committed Nov 27, 2024
1 parent 18f91ec commit 5d0e6b7
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 32 deletions.
53 changes: 34 additions & 19 deletions client/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const io = new Server(httpServer, {
pingInterval: 25000
});

// Global state
let votingState = {
currentStep: 1,
resolution: '',
Expand All @@ -25,20 +24,23 @@ let votingState = {
shares: []
};

let shareState = {
shares: [[]]
}

// Helper function to broadcast state
function broadcastState() {
io.emit('stateUpdate', votingState);
}

// Helper function to generate shares (mock implementation)
function generateShares(totalMembers) {
return Array.from(
{ length: totalMembers },
(_, i) => ({
id: i + 1,
share: `Share-${i + 1}-${Math.random().toString(36).substring(7)}`
})
);
// Helper function to broadcast shares to specific clients
function broadcastShares(shares) {
shares.forEach((share) => {
io.to(share.id).emit('shareReceived', {
id: share.id,
share: share.share
});
});
}

// Helper function to calculate voting results
Expand Down Expand Up @@ -160,29 +162,42 @@ io.on('connection', (socket) => {

votingState.votes[socket.id] = vote;
member.hasVoted = true;
broadcastState();

// Check if vote count has reached threshold
if (Object.keys(votingState.votes).length === votingState.threshold) {
votingState.currentStep = 4;
const initRes = await fetch('http://localhost:5882/api/init', {
await fetch('http://localhost:5882/api/init', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret: votingState.votes,
secret: Object.keys(votingState.votes).length,
threshold: votingState.threshold,
total_members: votingState.totalMembers
total_shares: votingState.totalMembers
})
});
console.log("init res:", initRes)

// get shares from Zig API
votingState.shares = generateShares(votingState.totalMembers);

//const results = calculateResults();
//io.emit('votingComplete', results);
const sharesRes = await fetch('http://localhost:5882/api/shares', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
count: votingState.members.length,
})
}).then(s => s.json());

const shares = sharesRes.shares.map((share, index) => ({
id: votingState.members[index].id,
share: share
}));

votingState.shares = shares;
broadcastShares(shares)
broadcastState();
console.log("shares res:", shares)
}

broadcastState();
//broadcastState();
callback?.({ success: true });
} catch (error) {
console.error('Vote error:', error);
Expand Down
51 changes: 38 additions & 13 deletions client/shamir-client/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type Step = 1 | 2 | 3 | 4 | 5;

interface Share {
id: number;
share: string;
share: { x: number, y: number };
}

interface ValidationError {
Expand Down Expand Up @@ -47,6 +47,7 @@ interface ClientState {
votes: Record<string, boolean>;
shares: Share[];
currentMemberId: string | null;
myShare?: { x: number, y: number };
}

const Client: React.FC = () => {
Expand All @@ -59,7 +60,8 @@ const Client: React.FC = () => {
members: [],
votes: {},
shares: [],
currentMemberId: null
currentMemberId: null,
myShare: undefined
});

const [errors, setErrors] = useState<ValidationError[]>([]);
Expand Down Expand Up @@ -152,29 +154,51 @@ const Client: React.FC = () => {
setState(current => ({
...current,
...newState,
currentMemberId: current.currentMemberId
currentMemberId: current.currentMemberId,
votes: newState.votes
}));
});

newSocket.on('votingComplete', (results) => {
setResult(results);
});

newSocket.on('shareReceived', (shareData) => {
// Store only this client's share
setState(current => ({
...current,
myShare: shareData.share
}));
});

setSocket(newSocket);

return () => {
newSocket.disconnect();
};
}, []);


// Effect to show join dialog
useEffect(() => {
if (state.currentStep === 3 && !state.currentMemberId) {
setShowJoinDialog(true);
}
}, [state.currentStep, state.currentMemberId]);

/* useEffect(() => {
socket?.on('shareReceived', (shareData) => {
// Store only this client's share
setState(current => ({
...current,
myShare: shareData.share
}));
});
return () => {
socket?.off('shareReceived');
};
}, [socket]); */

const handleSetup = async (e: React.FormEvent<HTMLFormElement>): Promise<void> => {
e.preventDefault();
setErrors([]);
Expand Down Expand Up @@ -339,7 +363,8 @@ const Client: React.FC = () => {
members: [],
votes: {},
shares: [],
currentMemberId: null
currentMemberId: null,
myShare: undefined
});
setShowJoinDialog(false);
setMemberName('');
Expand Down Expand Up @@ -520,7 +545,6 @@ const Client: React.FC = () => {
</Badge>
)}
</div>

{member.id === state.currentMemberId && !state.votes[member.id] && (
<div className="flex gap-2">
<Button
Expand Down Expand Up @@ -587,18 +611,19 @@ const Client: React.FC = () => {
<div className="space-y-6">
<Alert>
<AlertDescription>
Voting complete! Each member receives their share:
Voting complete!
</AlertDescription>
</Alert>
<ScrollArea className="h-[400px] rounded-md border p-4">
{state.shares.map((share) => (
<div key={share.id} className="mb-4 p-4 border rounded">
<Label>Board Member {share.id}</Label>
<div className="mt-2 p-2 bg-muted rounded">
<code className="text-sm">{share.share}</code>
{state.myShare && (
<div className="mb-4 p-4 border rounded">
<Label>Your Share</Label>
<div className="mt-2 p-2 bg-muted rounded flex flex-col gap-1">
<code className="text-sm">x: {state.myShare.x}</code>
<code className="text-sm">y: {state.myShare.y}</code>
</div>
</div>
))}
)}
</ScrollArea>
<Button onClick={() => setState(current => ({ ...current, currentStep: 5 }))}>
Proceed to Result Recovery
Expand Down

0 comments on commit 5d0e6b7

Please sign in to comment.