forked from JoshOrndorff/BitStory
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmyvisualize.js
108 lines (88 loc) · 2.94 KB
/
myvisualize.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
'use strict';
document.addEventListener('DOMContentLoaded', () => {
// Setup the blockchain visualization properties
var graphviz = d3.select('#graph').graphviz({fit: true, scale: 0.2});
// Docs at https://github.com/magjac/d3-graphviz
graphviz.zoom(false);
// But most don't work as advertised
//graphviz.fit(true);
//graphviz.scale(0.6); // https://github.com/magjac/d3-graphviz#graphviz_scale
// DOM Elements
const minerBox = document.getElementById('miner');
const parentBox = document.getElementById('parent');
const wordBox = document.getElementById('word');
const nonceBox = document.getElementById('nonce');
const hashDiv = document.getElementById('hash');
const publishButton = document.getElementById('publish');
// Event Handlers
publishButton.addEventListener('click', publishBlockHandler);
const socket = io(); // default: connect to host serving page
socket.on('gossip-block', addBlockToChain);
// Global block store and DOT store
const blocks = {};
const dotLines = [];
/**
* Builds a new block from the data in the DOM and publishes it
*/
function publishBlockHandler() {
// Build block from DOM values
const block = {
miner: minerBox.value,
parent: parentBox.value,
word: wordBox.value,
nonce: nonceBox.value,
hash: hashDiv.innerHTML,
}
// Send it out over the network
// As a _courtesy_ we won't send duplicate blocks over the network. This is _not_ a valid dos-prevention technique.
if (blocks.hasOwnProperty(block.hash)){
return;
}
socket.emit('publish-block', block);
// Add it to our own local graph
addBlockToChain(block);
}
/**
* Receives a block (either from a peer or created locally), adds it to the
* known blocks, and renders it in the DOM
* @param block The block that is being added
*/
function addBlockToChain(block) {
// If it's not actually a new block, don't re-add.
if (blocks.hasOwnProperty(block.hash)){
return;
}
// Add block to global block store
blocks[block.hash] = block;
// Update the visualization
dotLines.push(blockToDot(block));
const dotCode = `
digraph {
node [style="filled", shape="box"];
${dotLines.join('')}
}`;
//console.log(dotCode);
graphviz.renderDot(dotCode);
}
/**
* Turns a single block into a snippet of DOT code
*/
function blockToDot(b) {
// Generate a color from the miner's name
//TODO bad style relying on library imported from html directly
const color = sha256(b.miner).slice(0, 6)
// Genesis block situation
if (b.parent === "") {
b.parent = "genesis";
}
const nodeString = `
"${b.hash}"
[label ="word:${b.word}
nonce:${b.nonce}
parent:${b.parent}",
fillcolor="#${color}"];
`;
const edgeString = `"${b.hash}" -> "${b.parent}";`;
return nodeString + edgeString;
}
});