Bug & typo fixes. Smoother tx arrivals.

This commit is contained in:
Mononaut 2021-11-26 16:11:42 -06:00
parent 03c583bf59
commit f5ed1ad1d3
8 changed files with 31 additions and 16 deletions

View File

@ -1,6 +1,6 @@
{
"name": "bitfeed-client",
"version": "1.9.2",
"version": "2.0.0",
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",

View File

@ -45,7 +45,7 @@ function onClose () {
Bitfeed attempts to visualise this flow of information.
</p>
<p>
As new transactions are recieved by our nodes, they drop into the mempool to await confirmation.
As new transactions are received by our nodes, they drop into the mempool to await confirmation.
</p>
<p>
In <i>value mode</i>, squares representing transactions in the mempool are sized according to total output value,

View File

@ -332,7 +332,7 @@ async function generateInvoice () {
<div class="qr-container" class:paid={invoicePaid} class:expired={invoiceExpired}>
{#if invoicePaid }
<div class="invoice-icon"><Icon icon={tickIcon} color="white" /></div>
<h3 class="invoice-status">Recieved, Thanks!</h3>
<h3 class="invoice-status">Received, Thanks!</h3>
{:else if invoiceExpired}
<div class="invoice-icon"><Icon icon={timerIcon} color="white" /></div>
<h3 class="invoice-status">Request Expired</h3>

View File

@ -22,7 +22,7 @@ let settingConfig = {
label: 'Donation Info'
},
vbytes: {
label: 'Tx Size',
label: 'Size by',
type: 'pill',
falseLabel: 'value',
trueLabel: 'vbytes'

View File

@ -88,11 +88,11 @@ function formatBTC (sats) {
<p class="field hash">
TxID: { tx.id }
</p>
{#if tx.inputs && !tx.coinbase }<p class="field inputs">{ tx.inputs.length } inputs</p>
{#if tx.inputs && !tx.coinbase }<p class="field inputs">{ tx.inputs.length } input{#if tx.inputs.length != 1}s{/if}</p>
{:else if tx.coinbase }
<p class="field coinbase">Coinbase: { tx.coinbase.sigAscii }</p>
{/if}
{#if tx.outputs }<p class="field outputs">{ tx.outputs.length } outputs</p>{/if}
{#if tx.outputs }<p class="field outputs">{ tx.outputs.length } output{#if tx.outputs.length != 1}s{/if}</p>{/if}
<p class="field vbytes">{ integerFormat.format(tx.vbytes) } vbytes</p>
<p class="field value">
Total value: { formatBTC(tx.value) }

View File

@ -6,8 +6,9 @@ export default {
layoutHints: false,
fps: true,
websocket_path: '/ws/txs',
localSocket: false,
nofeed: false,
txDelay: 5000,
txDelay: 10000,
blockTimeout: 10000,
donationAddress: "bc1qthanksv78zs5jnmysvmuuuzj09aklf8jmm49xl",
donationHash: "5dfb3b419e38a1494f648337ce7052797b6fa4f2",

View File

@ -70,9 +70,12 @@ export default class TxController {
}
// Dual-strategy queue processing:
// - ensure transactions are queued for at least 2s
// - while queue is small, use jittered timeouts to smooth arrivals
// - when queue length exceeds 100, process iteratively to avoid unbounded growth
// - ensure transactions are queued for at least txDelay
// - when queue length exceeds 500, process iteratively to avoid unbounded growth
// - while queue is small, use jittered timeouts to evenly distribute arrivals
//
// transactions tend to arrive in groups, so for smoothest
// animation the queue should stay short but never empty.
processQueue () {
let done
let delay
@ -86,7 +89,11 @@ export default class TxController {
} else {
const timeSince = performance.now() - this.pendingTxs[0][1]
if (timeSince > this.txDelay) {
if (this.txDelay < this.maxTxDelay) this.txDelay += 10
//process the next tx in the queue, if it arrived longer ago than txDelay
if (this.txDelay < this.maxTxDelay) {
// slowly ramp up from 0 to maxTxDelay on start, so there's no wait for the first txs on page load
this.txDelay += 50
}
const tx = this.pendingTxs.shift()[0]
delete this.pendingMap[tx.id]
txQueueLength.decrement()
@ -94,16 +101,23 @@ export default class TxController {
this.poolScene.insert(this.txs[tx.id])
mempoolCount.increment()
} else {
// end the loop when the head of the queue arrived more recently than txDelay
done = true
delay = 2001 - timeSince
// schedule to continue processing when head of queue matures
delay = this.txDelay - timeSince
}
if (!done && this.pendingTxs.length < 100) {
if (this.pendingTxs.length < 500) {
// or the queue is under 500
done = true
}
// otherwise keep processing the queue
}
} else done = true
}
this.scheduleQueue(delay || (Math.random() * Math.max(1, (250 - this.pendingTxs.length))))
// randomly jitter arrival times so that txs enter more naturally
// with jittered delay inversely proportional to size of queue
let jitter = Math.random() * Math.max(1, (500 - this.pendingTxs.length))
this.scheduleQueue(delay || jitter)
}
scheduleQueue (delay) {

View File

@ -54,7 +54,7 @@ class TxStream {
if (this.reconnectBackoff) clearTimeout(this.reconnectBackoff)
if (!this.connected) {
console.log('......trying to reconnect websocket')
if (this.reconnectBackoff < 4000) this.reconnectBackoff *= 2
if (this.reconnectBackoff < 8000) this.reconnectBackoff *= 2
this.reconnectTimeout = setTimeout(() => { this.init() }, this.reconnectBackoff)
}
}
@ -130,7 +130,7 @@ class TxStream {
} else if (msg && msg.type === 'txn') {
window.dispatchEvent(new CustomEvent('bitcoin_tx', { detail: msg.txn }))
} else if (msg && msg.type === 'block') {
// console.log('Block recieved: ', msg.block)
// console.log('Block received: ', msg.block)
window.dispatchEvent(new CustomEvent('bitcoin_block', { detail: msg.block }))
} else {
// console.log('unknown message from websocket: ', msg)