Merge pull request #48 from bitfeed-project/v2.3

Patch v2.3
This commit is contained in:
Mononaut 2022-05-19 16:39:58 +01:00 committed by GitHub
commit 48b346ec18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 57 additions and 44 deletions

View File

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

View File

@ -359,7 +359,7 @@
</div> </div>
<div class="data-row spacer">&nbsp;</div> <div class="data-row spacer">&nbsp;</div>
<div class="data-row"> <div class="data-row">
<span class="data-field">Avg fee rate</span> <span class="data-field">avg fee rate</span>
{#if block.fees != null} {#if block.fees != null}
<span class="data-field">{ formatFee(block.avgFeerate) } sats/vbyte</span> <span class="data-field">{ formatFee(block.avgFeerate) } sats/vbyte</span>
{:else} {:else}

View File

@ -91,7 +91,7 @@ function expandAddresses(items, truncate) {
}) })
if (truncate && items.length > 100) { if (truncate && items.length > 100) {
const remainingCount = items.length - 100 const remainingCount = items.length - 100
const remainingValue = items.slice(100).reduce((acc, item) => { return acc + item.value }, 0) const remainingValue = items.slice(100).reduce((acc, item) => { return acc + (item.value || 0) }, 0)
expanded.push({ expanded.push({
address: `+ ${remainingCount} more`, address: `+ ${remainingCount} more`,
value: remainingValue, value: remainingValue,
@ -173,10 +173,7 @@ function calcSankeyLines(inputs, outputs, fee, value, totalHeight, svgWidth, flo
let maxXOffset = 0 let maxXOffset = 0
const inLines = inputs.map((input, index) => { const inLines = inputs.map((input, index) => {
if (input.value == null) { const weight = ((input.value || 0) / total) * flowWeight
return { line: [], weight: 0, index, total: inputs.length, in: true }
} else {
const weight = (input.value / total) * flowWeight
const height = ((index + 0.5) * rowHeight) const height = ((index + 0.5) * rowHeight)
const step = (weight / 2) const step = (weight / 2)
const line = [] const line = []
@ -202,7 +199,6 @@ function calcSankeyLines(inputs, outputs, fee, value, totalHeight, svgWidth, flo
cumThick += weight cumThick += weight
return { line, weight, index, total: inputs.length, in: true } return { line, weight, index, total: inputs.length, in: true }
}
}) })
inLines.forEach(line => { inLines.forEach(line => {
if (line.line.length) { if (line.line.length) {

View File

@ -166,6 +166,9 @@ function highlight () {
{#if !tx.coinbase && tx.fee != null } {#if !tx.coinbase && tx.fee != null }
<p class="field feerate">Fee rate: { numberFormat.format(tx.feerate.toFixed(2)) } sats/vbyte</p> <p class="field feerate">Fee rate: { numberFormat.format(tx.feerate.toFixed(2)) } sats/vbyte</p>
<p class="field fee">Fee: { numberFormat.format(tx.fee) } sats</p> <p class="field fee">Fee: { numberFormat.format(tx.fee) } sats</p>
{:else if !tx.coinbase && tx.fee == null}
<p class="field feerate">Fee rate: unavailable</p>
<p class="field fee">Fee: unavailable</p>
{/if} {/if}
<p class="field value"> <p class="field value">
Total value: { formatBTC(tx.value) } Total value: { formatBTC(tx.value) }

View File

@ -417,7 +417,7 @@ export default class TxController {
this.selectedTx = selected this.selectedTx = selected
selectedTx.set(selected) selectedTx.set(selected)
if (sameTx && selected) { if (sameTx && selected) {
if (!selected.is_inflated) { if (!selected.is_inflated || selected.is_partial) {
loading.increment() loading.increment()
await searchTx(selected.id) await searchTx(selected.id)
loading.decrement() loading.decrement()

View File

@ -49,10 +49,11 @@ export default class BitcoinTx {
this.view = new TxView(this) this.view = new TxView(this)
} }
mergeData ({ version, inflated, preview, id, value, fee, vbytes, numInputs, inputs, outputs, time, block }, isCoinbase=false) { mergeData ({ version, inflated, partial, preview, id, value, fee, vbytes, numInputs, inputs, outputs, time, block }, isCoinbase=false) {
this.setData({ this.setData({
version, version,
inflated: this.is_inflated || inflated, inflated: this.is_inflated || inflated,
partial: this.is_partial && partial,
preview: this.is_preview && preview, preview: this.is_preview && preview,
id, id,
value, value,
@ -66,9 +67,10 @@ export default class BitcoinTx {
}) })
} }
setData ({ version, inflated, preview, id, value, fee, vbytes, numInputs, inputs, outputs, time, block }, isCoinbase=false) { setData ({ version, inflated, partial, preview, id, value, fee, vbytes, numInputs, inputs, outputs, time, block }, isCoinbase=false) {
this.version = version this.version = version
this.is_inflated = !!inflated this.is_inflated = !!inflated
this.is_partial = !!partial
this.is_preview = !!preview this.is_preview = !!preview
this.id = id this.id = id
this.pixelPosition = { x: 0, y: 0, r: 0} this.pixelPosition = { x: 0, y: 0, r: 0}
@ -92,7 +94,7 @@ export default class BitcoinTx {
// is a coinbase transaction? // is a coinbase transaction?
this.isCoinbase = isCoinbase this.isCoinbase = isCoinbase
if (this.isCoinbase || this.fee == null || this.fee < 0) { if (this.isCoinbase || this.fee == null || this.fee < 0 || this.is_partial) {
this.fee = null this.fee = null
this.feerate = null this.feerate = null
} }

View File

@ -433,18 +433,20 @@ defmodule BitcoinStream.Mempool do
end end
defp sync_mempool_txns(pid, [next_chunk | rest], count) do defp sync_mempool_txns(pid, [next_chunk | rest], count) do
:timer.sleep(250);
case sync_batch(pid, next_chunk) do case sync_batch(pid, next_chunk) do
{:ok, batch_count} -> {:ok, batch_count} ->
Logger.info("synced #{batch_count + count} mempool transactions"); Logger.info("synced #{batch_count + count} mempool transactions");
sync_mempool_txns(pid, rest, batch_count + count) sync_mempool_txns(pid, rest, batch_count + count)
_ -> _ ->
:failed Logger.info("Failed to sync #{length(next_chunk)} mempool transactions");
sync_mempool_txns(pid, rest, count)
end end
end end
def sync_mempool_txns(pid, txns) do def sync_mempool_txns(pid, txns) do
sync_mempool_txns(pid, Enum.chunk_every(txns, 100), 0) sync_mempool_txns(pid, Enum.chunk_every(txns, 50), 0)
end end

View File

@ -21,6 +21,7 @@ defmodule BitcoinStream.Protocol.Transaction do
defstruct [ defstruct [
:version, :version,
:inflated, :inflated,
:partial,
:vbytes, :vbytes,
:inputs, :inputs,
:outputs, :outputs,
@ -99,6 +100,7 @@ defmodule BitcoinStream.Protocol.Transaction do
%__MODULE__{ %__MODULE__{
version: txn.version, version: txn.version,
inflated: false, inflated: false,
partial: true,
vbytes: txn.vbytes, vbytes: txn.vbytes,
inputs: inputs, inputs: inputs,
outputs: txn.outputs, outputs: txn.outputs,
@ -163,27 +165,35 @@ defmodule BitcoinStream.Protocol.Transaction do
:error :error
end end
defp inflate_inputs([], inflated, total, _fail_fast) do defp inflate_inputs([], inflated, total, _fail_fast, false) do
{:ok, inflated, total} {:ok, inflated, total}
end end
defp inflate_inputs([next_chunk | rest], inflated, total, fail_fast) do defp inflate_inputs([], inflated, total, _fail_fast, true) do
{:failed, inflated, 0}
end
defp inflate_inputs([next_chunk | rest], inflated, total, fail_fast, failed) do
if (failed) do
inflate_inputs(rest, inflated ++ next_chunk, total, fail_fast, true)
else
case inflate_batch(next_chunk, fail_fast) do case inflate_batch(next_chunk, fail_fast) do
{:ok, inflated_chunk, chunk_total} -> {:ok, inflated_chunk, chunk_total} ->
inflate_inputs(rest, inflated ++ inflated_chunk, total + chunk_total, fail_fast) inflate_inputs(rest, inflated ++ inflated_chunk, total + chunk_total, fail_fast, false)
_ -> _ ->
{:failed, inflated ++ next_chunk ++ rest, 0} inflate_inputs(rest, inflated ++ next_chunk, total, fail_fast, true)
end
end end
end end
def inflate_inputs([], nil, _fail_fast) do def inflate_inputs([], nil, _fail_fast, _failed) do
{ :failed, nil, 0 } { :failed, nil, 0 }
end end
# Retrieves cached inputs if available, # Retrieves cached inputs if available,
# otherwise inflates inputs in batches of up to 100 # otherwise inflates inputs in batches of up to 100
def inflate_inputs(_txid, inputs, fail_fast) do def inflate_inputs(_txid, inputs, fail_fast) do
inflate_inputs(Enum.chunk_every(inputs, 100), [], 0, fail_fast) inflate_inputs(Enum.chunk_every(inputs, 50), [], 0, fail_fast, false)
end end
end end

View File

@ -4,7 +4,7 @@ defmodule BitcoinStream.MixProject do
def project do def project do
[ [
app: :bitcoin_stream, app: :bitcoin_stream,
version: "2.3.1", version: "2.3.2",
elixir: "~> 1.10", elixir: "~> 1.10",
start_permanent: Mix.env() == :prod, start_permanent: Mix.env() == :prod,
deps: deps(), deps: deps(),