nip-13: add settings for mining difficulty and timeout

adding settings to change mining difficulty and timeout, so users
can change or disable pow. also added some explanation and link
to nip-13.

setting arbitrary low default to 16 zero mining difficulty and
5 seconds timeout.
pull/55/head
OFF0 1 year ago
parent a596121821
commit 898e7265c2
Signed by: offbyn
GPG Key ID: 94A2F643C51F37FA

@ -10,7 +10,7 @@
}
@media (orientation: portrait) {
.mbox {
padding: 0 calc(.5 * var(--gap));
padding: 0 var(--gap-half);
}
}
.mbox:last-child {

@ -43,6 +43,7 @@ label {
transition: background-color var(--transition-duration);
}
input[type="number"],
input[type="password"],
input[type="text"],
input[type="url"],
@ -54,6 +55,7 @@ textarea {
margin: 0 0 1.2rem 0;
padding: var(--padding);
}
input[type="number"]:focus,
input[type="password"]:focus,
input[type="text"]:focus,
input[type="url"]:focus,
@ -169,11 +171,13 @@ button:disabled {
margin-left: var(--gap);
}
.form-inline button,
.form-inline input[type="number"],
.form-inline input[type="text"],
.form-inline textarea {
margin: .4rem 0;
}
.form-inline input[type="number"],
.form-inline input[type="text"],
.form-inline textarea {
flex-basis: 50%;
@ -187,6 +191,46 @@ button:disabled {
flex-grow: 0;
}
label.number {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
gap: var(--gap);
padding: 0;
}
* + label.number {
margin: var(--gap) 0 0 0;
}
label.number span {
flex-grow: 1;
padding: 0 0 0 var(--padding);
}
label.number input[type="number"] {
align-self: baseline;
margin-bottom: 0;
}
@media (orientation: landscape) {
label.number span {
align-self: center;
}
label.number input[type="number"] + span {
padding: 0 var(--padding) 0 0;
}
}
@media (orientation: portrait) {
label.number {
flex-direction: column;
gap: var(--gap-half);
padding: 0;
}
label.number span {
padding: 0 var(--padding);
}
label.number input[type="number"] {
align-self: stretch;
}
}
button#publish {
align-self: end;
order: 2;

@ -83,6 +83,27 @@
<button type="submit" name="publish" tabindex="0" disabled>publish</button>
</div>
</form>
<form action="#" name="options">
<label class="number" for="miningTarget">
<span>
mining difficulty<br>
<small>
with which difficulty to try to mine a proof of work when publishing events, such as: notes, replies, reactions and profile updates.
use zero to disable mining.
difficulty is defined as the number of leading zero bits, read more about
<a href="https://github.com/nostr-protocol/nips/blob/master/13.md" target="_blank" rel="noopener noreferrer">proof of work (nip-13)</a>.
</small>
</span>
<input type="number" name="mining_target" step="1" min="0" max="256" id="miningTarget" value="16">
</label>
<label class="number" for="miningTimeout">
<span>
mining timeout<br>
<small>abort trying to find a proof if timeout (in seconds) exceeds. use 0 to mine without a time limit.</small>
</span>
<input type="number" name="mining_timeout" step="1" min="0" max="256" id="miningTimeout" value="5">
</label>
</form>
<form action="#" name="settings" autocomplete="new-password">
<label for="pubkey">public-key</label>
<input type="text" id="pubkey" autocomplete="off">

@ -15,6 +15,7 @@
--focus-outline: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color);
--font-small: 1.2rem;
--gap: 2.4rem;
--gap-half: 1.2rem;
--max-width: 96ch;
}

@ -40,10 +40,6 @@ let pubkey = localStorage.getItem('pub_key') || (() => {
return pubkey;
})();
// arbitrary difficulty, still experimenting.
// measured empirically, takes N sec on average to mine a text note event.
const difficulty = 16;
const subList = [];
const unSubAll = () => {
subList.forEach(sub => sub.unsub());
@ -756,6 +752,23 @@ function hideNewMessage(hide) {
newMessageDiv.hidden = hide;
}
// arbitrary difficulty default, still experimenting.
let difficulty = JSON.parse(localStorage.getItem('mining_target')) ?? 16;
const miningTargetInput = document.querySelector('#miningTarget');
miningTargetInput.addEventListener('input', (e) => {
localStorage.setItem('mining_target', miningTargetInput.valueAsNumber);
difficulty = miningTargetInput.valueAsNumber;
});
miningTargetInput.value = difficulty;
let timeout = JSON.parse(localStorage.getItem('mining_timeout')) ?? 5;
const miningTimeoutInput = document.querySelector('#miningTimeout');
miningTimeoutInput.addEventListener('input', (e) => {
localStorage.setItem('mining_timeout', miningTimeoutInput.valueAsNumber);
timeout = miningTimeoutInput.valueAsNumber;
});
miningTimeoutInput.value = timeout;
async function upvote(eventId, eventPubkey) {
const privatekey = localStorage.getItem('private_key');
const note = replyList.find(r => r.id === eventId) || textNoteList.find(n => n.id === (eventId));
@ -771,7 +784,7 @@ async function upvote(eventId, eventPubkey) {
content: '+',
tags,
created_at: Math.floor(Date.now() * 0.001),
}, difficulty, 10).catch(console.warn);
}, difficulty, timeout).catch(console.warn);
if (newReaction) {
const sig = await signEvent(newReaction, privatekey).catch(console.error);
if (sig) {
@ -810,7 +823,7 @@ writeForm.addEventListener('submit', async (e) => {
pubkey,
tags,
created_at: Math.floor(Date.now() * 0.001),
}, difficulty, 10).catch(console.warn);
}, difficulty, timeout).catch(console.warn);
if (newEvent) {
const sig = await signEvent(newEvent, privatekey).catch(onSendError);
if (sig) {
@ -954,7 +967,7 @@ profileForm.addEventListener('submit', async (e) => {
content: JSON.stringify(Object.fromEntries(form)),
tags: [],
created_at: Math.floor(Date.now() * 0.001),
}, difficulty, 10).catch(console.warn);
}, difficulty, timeout).catch(console.warn);
if (newProfile) {
const sig = await signEvent(newProfile, privatekey).catch(console.error);
if (sig) {
@ -1031,8 +1044,12 @@ function validatePow(evt) {
*
* powEvent returns a rejected promise if the funtion runs for longer than timeout.
* a zero timeout makes mineEvent run without a time limit.
* a zero mining target just resolves the promise without trying to find a 'nonce'.
*/
function powEvent(evt, difficulty, timeout = 0) {
function powEvent(evt, difficulty, timeout) {
if (difficulty === 0) {
return Promise.resolve(evt);
}
return new Promise((resolve, reject) => {
const worker = new Worker('./worker.js');

@ -45,7 +45,7 @@ input[type="radio"]:checked + label {
.tab-content {
max-width: var(--max-width);
min-height: 200px;
padding: calc(.5 * var(--gap)) 0 100px 0;
padding: var(--gap-half) 0 100px 0;
}
.tabbed {
align-items: start;

Loading…
Cancel
Save