Skip to content

Commit

Permalink
Merge pull request #48 from bitfeed-project/v2.3
Browse files Browse the repository at this point in the history
Patch v2.3
  • Loading branch information
mononaut authored May 19, 2022
2 parents 13e6382 + d3c84c7 commit 48b346e
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 49 deletions.
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bitfeed-client",
"version": "2.3.1",
"version": "2.3.2",
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/BlockInfo.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@
</div>
<div class="data-row spacer">&nbsp;</div>
<div class="data-row">
<span class="data-field">Avg fee rate</span>
<span class="data-field">avg fee rate</span>
{#if block.fees != null}
<span class="data-field">{ formatFee(block.avgFeerate) } sats/vbyte</span>
{:else}
Expand Down
58 changes: 27 additions & 31 deletions client/src/components/TransactionOverlay.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function expandAddresses(items, truncate) {
})
if (truncate && 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({
address: `+ ${remainingCount} more`,
value: remainingValue,
Expand Down Expand Up @@ -173,36 +173,32 @@ function calcSankeyLines(inputs, outputs, fee, value, totalHeight, svgWidth, flo
let maxXOffset = 0
const inLines = inputs.map((input, index) => {
if (input.value == null) {
return { line: [], weight: 0, index, total: inputs.length, in: true }
} else {
const weight = (input.value / total) * flowWeight
const height = ((index + 0.5) * rowHeight)
const step = (weight / 2)
const line = []
const yOffset = 0.5
line.push({ x: triangleWidth, y: height })
line.push({ x: triangleWidth + (0.25 * svgWidth), y: height })
line.push({ x: 0.425 * svgWidth, y: mergeOffset + cumThick + step + yOffset })
line.push({ x: (0.5 * svgWidth) + 1, y: mergeOffset + cumThick + step + yOffset })
const dy = line[1].y - line[2].y
const dx = line[2].x - line[1].x
const miterOffset = getMiterOffset(weight, dy, dx)
xOffset += miterOffset
line[1].x += xOffset
line[2].x += xOffset
xOffset += miterOffset
maxXOffset = Math.max(xOffset, maxXOffset)
// inLines.push({ line, weight })
// inLines.push({ line: [{x: line[1].x + miterOffset, y: line[1].y - (weight / 2)}, {x: line[2].x + miterOffset, y: line[2].y - (weight / 2)}], weight: 1})
cumThick += weight
return { line, weight, index, total: inputs.length, in: true }
}
const weight = ((input.value || 0) / total) * flowWeight
const height = ((index + 0.5) * rowHeight)
const step = (weight / 2)
const line = []
const yOffset = 0.5
line.push({ x: triangleWidth, y: height })
line.push({ x: triangleWidth + (0.25 * svgWidth), y: height })
line.push({ x: 0.425 * svgWidth, y: mergeOffset + cumThick + step + yOffset })
line.push({ x: (0.5 * svgWidth) + 1, y: mergeOffset + cumThick + step + yOffset })
const dy = line[1].y - line[2].y
const dx = line[2].x - line[1].x
const miterOffset = getMiterOffset(weight, dy, dx)
xOffset += miterOffset
line[1].x += xOffset
line[2].x += xOffset
xOffset += miterOffset
maxXOffset = Math.max(xOffset, maxXOffset)
// inLines.push({ line, weight })
// inLines.push({ line: [{x: line[1].x + miterOffset, y: line[1].y - (weight / 2)}, {x: line[2].x + miterOffset, y: line[2].y - (weight / 2)}], weight: 1})
cumThick += weight
return { line, weight, index, total: inputs.length, in: true }
})
inLines.forEach(line => {
if (line.line.length) {
Expand Down
3 changes: 3 additions & 0 deletions client/src/components/TxInfo.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ function highlight () {
{#if !tx.coinbase && tx.fee != null }
<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>
{:else if !tx.coinbase && tx.fee == null}
<p class="field feerate">Fee rate: unavailable</p>
<p class="field fee">Fee: unavailable</p>
{/if}
<p class="field value">
Total value: { formatBTC(tx.value) }
Expand Down
2 changes: 1 addition & 1 deletion client/src/controllers/TxController.js
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ export default class TxController {
this.selectedTx = selected
selectedTx.set(selected)
if (sameTx && selected) {
if (!selected.is_inflated) {
if (!selected.is_inflated || selected.is_partial) {
loading.increment()
await searchTx(selected.id)
loading.decrement()
Expand Down
8 changes: 5 additions & 3 deletions client/src/models/BitcoinTx.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ export default class BitcoinTx {
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({
version,
inflated: this.is_inflated || inflated,
partial: this.is_partial && partial,
preview: this.is_preview && preview,
id,
value,
Expand All @@ -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.is_inflated = !!inflated
this.is_partial = !!partial
this.is_preview = !!preview
this.id = id
this.pixelPosition = { x: 0, y: 0, r: 0}
Expand All @@ -92,7 +94,7 @@ export default class BitcoinTx {

// is a coinbase transaction?
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.feerate = null
}
Expand Down
6 changes: 4 additions & 2 deletions server/lib/mempool.ex
Original file line number Diff line number Diff line change
Expand Up @@ -433,18 +433,20 @@ defmodule BitcoinStream.Mempool do
end

defp sync_mempool_txns(pid, [next_chunk | rest], count) do
:timer.sleep(250);
case sync_batch(pid, next_chunk) do
{:ok, batch_count} ->
Logger.info("synced #{batch_count + count} mempool transactions");
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

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


Expand Down
28 changes: 19 additions & 9 deletions server/lib/protocol/transaction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ defmodule BitcoinStream.Protocol.Transaction do
defstruct [
:version,
:inflated,
:partial,
:vbytes,
:inputs,
:outputs,
Expand Down Expand Up @@ -99,6 +100,7 @@ defmodule BitcoinStream.Protocol.Transaction do
%__MODULE__{
version: txn.version,
inflated: false,
partial: true,
vbytes: txn.vbytes,
inputs: inputs,
outputs: txn.outputs,
Expand Down Expand Up @@ -163,27 +165,35 @@ defmodule BitcoinStream.Protocol.Transaction do
:error
end

defp inflate_inputs([], inflated, total, _fail_fast) do
defp inflate_inputs([], inflated, total, _fail_fast, false) do
{:ok, inflated, total}
end

defp inflate_inputs([next_chunk | rest], inflated, total, fail_fast) do
case inflate_batch(next_chunk, fail_fast) do
{:ok, inflated_chunk, chunk_total} ->
inflate_inputs(rest, inflated ++ inflated_chunk, total + chunk_total, fail_fast)
_ ->
{:failed, inflated ++ next_chunk ++ rest, 0}
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
{:ok, inflated_chunk, chunk_total} ->
inflate_inputs(rest, inflated ++ inflated_chunk, total + chunk_total, fail_fast, false)
_ ->
inflate_inputs(rest, inflated ++ next_chunk, total, fail_fast, true)
end
end
end

def inflate_inputs([], nil, _fail_fast) do
def inflate_inputs([], nil, _fail_fast, _failed) do
{ :failed, nil, 0 }
end

# Retrieves cached inputs if available,
# otherwise inflates inputs in batches of up to 100
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
Expand Down
2 changes: 1 addition & 1 deletion server/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule BitcoinStream.MixProject do
def project do
[
app: :bitcoin_stream,
version: "2.3.1",
version: "2.3.2",
elixir: "~> 1.10",
start_permanent: Mix.env() == :prod,
deps: deps(),
Expand Down

0 comments on commit 48b346e

Please sign in to comment.