mirror of
https://github.com/Retropex/bitfeed.git
synced 2025-05-13 03:30:47 +02:00
Bug & typo fixes. Smoother tx arrivals.
This commit is contained in:
parent
03c583bf59
commit
f5ed1ad1d3
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bitfeed-client",
|
||||
"version": "1.9.2",
|
||||
"version": "2.0.0",
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"dev": "rollup -c -w",
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
|
@ -22,7 +22,7 @@ let settingConfig = {
|
||||
label: 'Donation Info'
|
||||
},
|
||||
vbytes: {
|
||||
label: 'Tx Size',
|
||||
label: 'Size by',
|
||||
type: 'pill',
|
||||
falseLabel: 'value',
|
||||
trueLabel: 'vbytes'
|
||||
|
@ -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) }
|
||||
|
@ -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",
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user