diff --git a/client/package.json b/client/package.json index 211e9d4..36fcb13 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "bitfeed-client", - "version": "2.3.2", + "version": "2.3.3", "scripts": { "build": "rollup -c", "dev": "rollup -c -w", diff --git a/client/src/components/TransactionOverlay.svelte b/client/src/components/TransactionOverlay.svelte index bf0a028..04b551b 100644 --- a/client/src/components/TransactionOverlay.svelte +++ b/client/src/components/TransactionOverlay.svelte @@ -3,7 +3,7 @@ import Overlay from '../components/Overlay.svelte' import Icon from './Icon.svelte' import BookmarkIcon from '../assets/icon/cil-bookmark.svg' import { longBtcFormat, numberFormat, feeRateFormat, dateFormat } from '../utils/format.js' -import { exchangeRates, settings, sidebarToggle, newHighlightQuery, highlightingFull, detailTx, pageWidth, latestBlockHeight, highlightInOut, loading, urlPath, currentBlock, overlay, explorerBlockData } from '../stores.js' +import { exchangeRates, settings, sidebarToggle, newHighlightQuery, highlightingFull, detailTx, pageWidth, latestBlockHeight, highlightInOut, loading, urlPath, currentBlock, overlay, explorerBlock } from '../stores.js' import { formatCurrency } from '../utils/fx.js' import { hlToHex, mixColor, teal, purple } from '../utils/color.js' import { SPKToAddress } from '../utils/encodings.js' @@ -298,9 +298,11 @@ async function goToBlock(e) { let hash = $detailTx.block.hash || $detailTx.block.id let height = $detailTx.block.height if (hash === $currentBlock.id) { + onClose() $overlay = null } else if (height == $latestBlockHeight) { - $explorerBlockData = null + onClose() + $explorerBlock = null $overlay = null } else if (hash) { loading.increment() diff --git a/client/src/controllers/Router.js b/client/src/controllers/Router.js index cddbec9..27c2dae 100644 --- a/client/src/controllers/Router.js +++ b/client/src/controllers/Router.js @@ -1,4 +1,4 @@ -import { urlPath, settings, loading, detailTx, highlightInOut, explorerBlockData, overlay } from '../stores.js' +import { urlPath, settings, loading, detailTx, highlightInOut, explorerBlock, overlay } from '../stores.js' import { searchTx, searchBlockHash, searchBlockHeight } from '../utils/search.js' export default class Router { @@ -37,7 +37,7 @@ export default class Router { detailTx.set(null) highlightInOut.set(null) urlPath.set("/") - explorerBlockData.set(null) + explorerBlock.set(null) overlay.set(null) } else { switch (parts[1]) { diff --git a/client/src/controllers/TxController.js b/client/src/controllers/TxController.js index 3da8fa3..6b00ece 100644 --- a/client/src/controllers/TxController.js +++ b/client/src/controllers/TxController.js @@ -6,7 +6,7 @@ import BitcoinBlock from '../models/BitcoinBlock.js' import TxSprite from '../models/TxSprite.js' import { FastVertexArray } from '../utils/memory.js' import { searchTx, fetchSpends, addSpends } from '../utils/search.js' -import { overlay, txCount, mempoolCount, mempoolScreenHeight, blockVisible, currentBlock, selectedTx, detailTx, blockAreaSize, highlight, colorMode, blocksEnabled, latestBlockHeight, explorerBlockData, blockTransitionDirection, loading, urlPath } from '../stores.js' +import { overlay, txCount, mempoolCount, mempoolScreenHeight, blockVisible, currentBlock, selectedTx, detailTx, blockAreaSize, highlight, colorMode, blocksEnabled, latestBlockHeight, explorerBlock, blockTransitionDirection, loading, urlPath } from '../stores.js' import config from "../config.js" import { tick } from 'svelte'; @@ -48,9 +48,9 @@ export default class TxController { colorMode.subscribe(mode => { this.setColorMode(mode) }) - explorerBlockData.subscribe(blockData => { - if (blockData) { - this.exploreBlock(blockData) + explorerBlock.subscribe(block => { + if (block) { + this.exploreBlock(block) } else { this.resumeLatest() } @@ -168,21 +168,18 @@ export default class TxController { }).map(key => { return { ...this.txs[key], - inputs: this.txs[key].inputs.map(input => { return {...input, script_pub_key: null, value: null }}), + inputs: this.txs[key].inputs ? this.txs[key].inputs.map(input => { return {...input, script_pub_key: null, value: null }}) : [], } })] }) } - addBlock (blockData, realtime=true) { + addBlock (block, realtime=true) { // discard duplicate blocks - if (!blockData || !blockData.id || this.knownBlocks[blockData.id]) { + if (!block || !block.id || this.knownBlocks[block.id]) { return } - let block - block = new BitcoinBlock(blockData) - latestBlockHeight.set(block.height) // this.knownBlocks[block.id] = true if (this.clearBlockTimeout) clearTimeout(this.clearBlockTimeout) @@ -285,9 +282,7 @@ export default class TxController { return block } - async exploreBlock (blockData) { - const block = blockData.isBlock ? blockData : new BitcoinBlock(blockData) - + async exploreBlock (block) { if (this.block && this.block.id === block.id) { this.showBlock() return diff --git a/client/src/controllers/TxStream.js b/client/src/controllers/TxStream.js index c064f54..a688075 100644 --- a/client/src/controllers/TxStream.js +++ b/client/src/controllers/TxStream.js @@ -1,4 +1,4 @@ -import { serverConnected, serverDelay, lastBlockId } from '../stores.js' +import { serverConnected, serverDelay, lastBlockId, latestBlockHeight } from '../stores.js' import config from '../config.js' import api from '../utils/api.js' import { fetchBlockByHash } from '../utils/search.js' @@ -6,7 +6,8 @@ import { fetchBlockByHash } from '../utils/search.js' let mempoolTimer let lastBlockSeen lastBlockId.subscribe(val => { lastBlockSeen = val }) - +let latestBlockHeightVal +latestBlockHeight.subscribe(val => { latestBlockHeightVal = val }) class TxStream { constructor () { @@ -122,8 +123,11 @@ class TxStream { async fetchBlock (id, calledOnLoad) { if (!id) return if (id !== lastBlockSeen) { - const blockData = await fetchBlockByHash(id) - window.dispatchEvent(new CustomEvent('bitcoin_block', { detail: { block: blockData, realtime: !calledOnLoad} })) + const block = await fetchBlockByHash(id) + // ignore this block if we've downloaded a newer one while we were waiting + if (block.height >= latestBlockHeightVal) { + window.dispatchEvent(new CustomEvent('bitcoin_block', { detail: { block, realtime: !calledOnLoad} })) + } } else { console.log('already seen block ', lastBlockSeen) } diff --git a/client/src/stores.js b/client/src/stores.js index 3e75a7f..bf7ca51 100644 --- a/client/src/stores.js +++ b/client/src/stores.js @@ -179,7 +179,7 @@ export const blocksEnabled = derived([settings], ([$settings]) => { export const latestBlockHeight = writable(null) export const highlightInOut = writable(null) export const loading = createCounter() -export const explorerBlockData = writable(null) +export const explorerBlock = writable(null) export const blockTransitionDirection = writable(null) export const urlPath = writable(null) diff --git a/client/src/utils/search.js b/client/src/utils/search.js index e300e9a..7c08f37 100644 --- a/client/src/utils/search.js +++ b/client/src/utils/search.js @@ -1,7 +1,7 @@ import api from './api.js' import BitcoinTx from '../models/BitcoinTx.js' import BitcoinBlock from '../models/BitcoinBlock.js' -import { detailTx, selectedTx, currentBlock, explorerBlockData, overlay, highlightInOut, urlPath } from '../stores.js' +import { detailTx, selectedTx, currentBlock, explorerBlock, overlay, highlightInOut, urlPath } from '../stores.js' import { addressToSPK } from './encodings.js' // Quick heuristic matching to guess what kind of search a query is for @@ -154,7 +154,7 @@ async function fetchBlockByHash (hash) { if (blockData) { if (blockData.id) { block = new BitcoinBlock(blockData) - } else block = BitcoinBlock.decompress(blockData) + } else block = new BitcoinBlock(BitcoinBlock.decompress(blockData)) } if (block && block.id) { console.log('downloaded block', block.id) @@ -255,7 +255,7 @@ export async function searchBlockHash (hash) { const searchResult = await fetchBlockByHash(hash) if (searchResult) { if (searchResult.id) { - explorerBlockData.set(searchResult) + explorerBlock.set(searchResult) } return null } else { @@ -274,7 +274,7 @@ export async function searchBlockHeight (height) { const searchResult = await fetchBlockByHeight(height) if (searchResult) { if (searchResult.id) { - explorerBlockData.set(searchResult) + explorerBlock.set(searchResult) } return null } else { diff --git a/server/mix.exs b/server/mix.exs index 23bec32..de8185c 100644 --- a/server/mix.exs +++ b/server/mix.exs @@ -4,7 +4,7 @@ defmodule BitcoinStream.MixProject do def project do [ app: :bitcoin_stream, - version: "2.3.2", + version: "2.3.3", elixir: "~> 1.10", start_permanent: Mix.env() == :prod, deps: deps(),