-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.html
161 lines (143 loc) · 5.02 KB
/
index.html
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>WebGL2 Nano Currency Proof of Work Generation Demo</title>
<script src="nano-webgl-pow.js"></script>
<script src="demo/startThreads.js"></script>
<style>
body { font-family: sans-serif; max-width: 690px; margin: 20px auto; padding: 0 10px;}
h1 { font-size: 110%; }
label { display: block; margin-bottom:10px;}
label span { display:inline-block; width: 70px; }
input.hash { width: 100%; padding: 4px; font-size: 110%; box-sizing:border-box; }
button { margin: 10px 0; }
</style>
</head>
<body>
<h1>WebGL2 Nano Currency Proof of Work Generation Demo</h1>
<p><a href="/~https://github.com/numtel/nano-webgl-pow">View repository</a></p>
<p>This demo will generate work values for a given hash.</p>
<p>Use the method selector to compare this implementation (WebGL) to <a href="/~https://github.com/jaimehgb/RaiBlocksWebAssemblyPoW">jaimehgb's WebAssembly version</a>, as well as running both implementations in parallel.</p>
<p>WebGL generation requires this page to remain open. If you switch to another tab, the generation will pause.</p>
<form>
<label>
Previous block hash:
<input class="hash" value="1A66A5CEF5B149FEAE8F680ED7E32956F3B45A3D7914660265178BDED16446C8" />
</label>
<label>
<span>Method:</span>
<select>
<option value="0">WebGL</option>
<option value="1">WebAssembly (jaimehgb)</option>
<option value="2">Both at the same time</option>
</select>
</label>
<label>
<span>Count:</span>
<input type="number" value="1" min="1" max="1000" />
</label>
<button>Calculate</button>
</form>
<ul id="status"></ul>
<script>
const form = document.forms[0];
const status = document.getElementById('status');
const generationMethods = [
function webgl(hash, callback) {
try {
const workValue = NanoWebglPow(hash, callback,
n => {
setStatus('Calculated ' + n + ' frames...');
}
);
} catch(error) {
if(error.message === 'webgl2_required')
setStatus('WebGL 2 is required for this demo');
else if(error.message === 'invalid_hash')
setStatus('Block hash must be 64 character hex string');
else
setStatus('An error has occurred');
throw error;
}
},
function wasm(hash, callback) {
const workers = pow_initiate(undefined, 'demo/');
pow_callback(workers, hash, () => {}, callback);
},
function both(hash, callback) {
let finished = false;
const workers = pow_initiate(undefined, 'demo/');
pow_callback(workers, hash, () => {}, workValue => {
// Stop WebGl from continuing
finished = true;
callback && callback(workValue, null, 'WebAssembly');
callback = null;
});
try {
NanoWebglPow(hash,
(workValue, n) => {
// Stop WebAssembly from continuing
pow_terminate(workers);
callback && callback(workValue, n, 'WebGL');
callback = null;
},
n => {
// Bail if WebAssembly finished already
if(finished) return true;
setStatus('Calculated ' + n + ' frames...');
}
);
} catch(error) {
if(error.message === 'webgl2_required')
setStatus('WebGL 2 is required for this demo');
else if(error.message === 'invalid_hash')
setStatus('Block hash must be 64 character hex string');
else
setStatus('An error has occurred');
throw error;
}
}
];
function generateMany(method, hash, count, callback, soFar) {
soFar = soFar || [];
const start = Date.now();
method(hash, (workValue, n, whichMethod) => {
const calcTime = (Date.now() - start) / 1000;
let hashes;
// Only WebGL method provides data for calculating hashes/second
if(n) hashes = NanoWebglPow.width * NanoWebglPow.height * n;
setStatus(
'In ' + calcTime + ' seconds, found work value: ' +
workValue + (whichMethod ? ' using ' + whichMethod : '')
+ (hashes ? ' @ ' + Math.round(hashes / calcTime / 1000) + ' kilohash/second' : ''));
soFar.push(calcTime);
if(soFar.length >= count) callback(soFar);
else generateMany(method, hash, count, callback, soFar);
});
}
function setStatus(text) {
status.innerHTML = '<li>' + text + '</li>' + status.innerHTML;
}
form.addEventListener('submit', e => {
e.preventDefault();
const start = Date.now();
const hash = form.elements[0].value;
const method = parseInt(form.elements[1].value, 10);
const count = parseInt(form.elements[2].value, 10);
setStatus('Starting generation...');
generateMany(generationMethods[method], hash, count, calcTimes => {
const average = calcTimes.reduce((out, time, index) => {
out+=time;
// Return average at end
if(index + 1 === calcTimes.length) return out/calcTimes.length;
// Not the end, keep building sum
return out;
}, 0);
if(count > 1)
setStatus('Generated ' + count + ' work values in average time of ' + average + ' seconds.');
});
}, false);
</script>
</body>
</html>