chore: replace master with upstream-latest#25
Conversation
* chore(erc4626): adding ws endpoint to fetch 4626 data for token * chore(erc4626): evolve getErc4626 into getContractInfo endpoint * chore(erc4626): unify getAccountInfo with getContractInfo * chore(erc4626): cleanup * chore(erc4626): add EVM-only guard for getContractInfo * chore(erc4626): add EVM-only guard for getAccountInfo * chore(erc4626): add tron spec to ContractInfoResult, Token and TokenTransfer
…ddress LRU eviction
Previously, the entire cfAddressAliases column family was loaded into a map at startup via InitAddressAliasRecords and held forever. On Ethereum mainnet (~1.5–2.5M ENS records at ~140 B/entry) this cost ~280–350 MB resident on every archive instan and there was no eviction. Replace with a 100k-entry LRU that lazy-loads on GetAddressAlias miss via a cfAddressAliases point lookup. The CF is small and bloom-filtered, so misses are sub-millisecond. The store path populates the LRU directly, keeping recently-written aliases hot. InitAddressAliasRecords and its call from LoadInternalState are removed. Negative results are not cached — addresses without an alias hit RocksDB on each render, but the CF's bloom filter makes this cheap and keeps the LRU focused on real aliases.
3x bigger db cache is not necessary anymore after recent syncing optimizations
…other fast EVM chains
Bitcoin mainnet contains a handful of historical transactions whose 4-byte version field, interpreted as unsigned, exceeds int32 max.
Honor X-Real-Ip when the TCP peer is on a loopback/RFC1918/ULA/link-local network, i.e. an upstream proxy on the same host or LAN. For direct internet peers the header stays ignored so it can't be used to spoof past the per-IP rate limiter. Auto-detected via netip predicates, no config.
Background ticker that calls limiter.sweep() every cleanupInterval, so TTL-expired idle entries are evicted even when no new connections arrive to drive cleanup. The goroutine is started once in NewWebsocketServer
Add <NETWORK>_WS_TRUSTED_PROXIES env var to extend X-Real-Ip trust beyond loopback/RFC1918 for non-Cloudflare deployments. Fails startup on /0 or otherwise overly broad prefixes (< /8 IPv4, < /16 IPv6) so misconfig can't silently turn the header into a spoofing primitive.
Wrap the four DB-touching go ... spawn sites with a sync.WaitGroup gate and add WebsocketServer.Shutdown(ctx) that flips a shuttingDown flag, closes all registered channels, and waits for in-flight goroutines to drain. PublicServer.Shutdown now drives it after http.Server.Shutdown, so a long getAccountInfo can no longer race rocksdb_close in cgo and SIGSEGV on graceful restart.
Blockbook reads operator secrets and per-coin tunables (INFURA_API_KEY, COINGECKO_API_KEY, <coin>_* limits, ...) from its process environment at runtime. These were provided out of band via systemd DefaultEnvironment in /etc/systemd/system.conf, hand-maintained per host. Add an optional EnvironmentFile=-/etc/blockbook/blockbook.env to the blockbook service unit so a single file can supply them per host. The leading '-' keeps the file optional, so public/community installs and existing hosts that still use DefaultEnvironment are unaffected when it is absent; a unit-level value also overrides a DefaultEnvironment value for the same key, allowing a no-flag-day migration off system.conf. On the dev deploy path (bbcli -> deploy.yml on self-hosted runners) the file is materialized from the BB_BLOCKBOOK_ENV GitHub Actions secret before the service restart; the step is a no-op when the secret is unset so it is safe to merge before the secret exists. Prod hosts will render the same file via bbctl. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The set of BB_ build-time variable prefixes was duplicated in three places that had to be hand-synced: the Makefile forwarding regex, the export-env-vars action normalizer, and templates.go. A drift failed silently (e.g. a var exported to GITHUB_ENV but absent from the Makefile regex never reaches the build). Introduce build/bb-build-var-prefixes.txt as the canonical list. The Makefile now derives the forwarding match from it (output verified identical to the old regex; BB_BUILD_ENV continues to be forwarded separately via -e on each docker run), and the action reads it for coin-alias normalization. templates.go keeps its typed constants but a new test (TestCanonicalPrefixesCoverTemplateConsumers) asserts every prefix it relies on is present in the file, so drift now fails in CI instead of at build time. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The materialize step wrote the env file with `tee` (umask default, ~0644) and only then chmod'd it to 0600, leaving a brief window where the secrets were world-readable on the runner. Pre-create the file 0600 root:root with `install /dev/null`; tee then truncates it without changing the mode, closing the window and dropping the now-redundant chown/chmod. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…sconfigured EVM coins that set `alternative_estimate_fee` to "infura"/"1inch" require the matching API-key env var (INFURA_API_KEY / ONE_INCH_API_KEY). Previously a missing key only logged an error and silently reverted to default fee estimation, so a misconfigured node started and served wrong fees. Propagate the provider-construction error from initAlternativeFeeProvider through the existing InitAlternativeProviders path (already checked by every EVM coin), so a node whose config selects a provider it cannot construct fails to start instead of degrading silently. A coin with no provider configured stays a no-op. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The fail-fast added in c468fa3 makes EVM chain initialization abort when a configured alternative_estimate_fee provider cannot be built because its API-key env var is unset. Integration tests render the production coin configs and call chain.Initialize(); avalanche selects "infura", but the test environment is never given INFURA_API_KEY (the CI Makefile only forwards BB_* vars), so TestIntegration/avalanche=main/rpc now fails during init. Supply harmless placeholder keys for the EVM fee providers at the start of the integration run so the chain initializes and falls back to default fee estimation; the background fee fetch just 401s and is ignored. These tests assert RPC/sync behavior, not fees, and a real key in the environment is still respected. Production fail-fast is unchanged and covered by the unit tests in bchain/coins/eth. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
BB_BLOCKBOOK_ENV was redundant (BB already stands for Blockbook) and did not convey that its content is the runtime environment file. Rename the GitHub Actions secret reference to BB_RUNTIME_ENV, consistent with the new BB_ADMIN_USER/BB_ADMIN_PASSWORD runtime variables. The GitHub repository secret must be renamed to match; until it is, the materialize step no-ops and leaves blockbook.env untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The internal server binds all interfaces by default (configs/coins/*: internal_binding_template is ":<port>"), so its /admin pages and state-mutating POST handlers (internal-data refetch, contract-info updates) were reachable unauthenticated by any peer that could reach the port. Gate the whole /admin surface behind HTTP Basic auth, credentials from BB_ADMIN_USER/BB_ADMIN_PASSWORD (delivered via blockbook.env). Basic auth (rather than a bearer token) lets the admin HTML pages and forms be used directly from a browser via its native login prompt, and still works for scripts via curl -u. The surface is fail-closed: unless both variables are set, every /admin route returns 503. /metrics, the status page and static assets are unaffected, so Prometheus scraping is unchanged. - A trailing-slash catch-all (/admin/) is gated too, so unregistered or trailing-slash paths can't fall through to the unauthenticated index. - Credentials are trimmed of surrounding whitespace at load (a stray newline in blockbook.env won't lock the operator out) and only their SHA-256 digests are retained; user and password are compared in constant time with both comparisons evaluated before being combined. Transport is the existing self-signed cert, intended for a trusted, firewalled internal segment (see docs/env.md). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The /admin/ trailing-slash catch-all added to gate unknown admin subpaths also returned 404 for a bare "/admin/", so navigating to the natural trailing-slash URL dead-ended after login instead of showing the admin index (served at /admin, no trailing slash). Redirect "/admin/" to the canonical "/admin" while still returning a gated 404 for any genuinely unknown /admin/* path, so the subtree stays authenticated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…di, nile) (trezor#1575) * fix(tests): keep testnet network suffix in matchable test name getMatchableName/matchable_name collapsed every "<coin>_testnet*" key to "<coin>=test", so sibling testnets (sepolia vs hoodi, testnet vs testnet4) shared one subtest name. The deploy connectivity regex built for one testnet then also selected its siblings, so a deploy could fail because an unrelated testnet's blockbook was unreachable. Preserve the network suffix after "_testnet" so the mapping is injective ("ethereum_testnet_sepolia" -> "ethereum=test_sepolia"), and anchor each name in the connectivity regex so "bitcoin=test" no longer substring-matches "bitcoin=test4". Add Go and Python regression guards and update the docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(integration): add tron_testnet_nile integration tests Mirror the mainnet tron entry (connectivity http, api, rpc). The rpc fixture tests/rpc/testdata/tron_testnet_nile.json already exists, and the BB_DEV_* RPC/API repository variables for tron_testnet_nile are already provisioned, so no new GitHub variables are required. Adding the connectivity group lets the deploy pipeline gate tron_testnet_nile on backend + Blockbook reachability, and the api group enables the post-deploy OpenAPI e2e suite for it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(integration): add ethereum_testnet_sepolia and _hoodi integration tests Give both Ethereum testnets connectivity (http + ws) and the no-fixture EVM api list (the same list used by avalanche/arbitrum/optimism). The fixture-backed EVM tests (ERC4626, contract-info, protocols) are intentionally omitted because they require tests/openapi/fixtures/<coin>.json with mainnet contract addresses, which only exist for ethereum and base; no rpc group is added for the same reason (no tests/rpc/testdata/<coin>.json fixture yet). The BB_DEV_* RPC/API repository variables for both testnets already exist (the RPC URLs resolve via the *_archive fallback), so no new GitHub variables are required. Connectivity gates their deploys and api enables the OpenAPI e2e suite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(integration): support disabling a coin via tests.json "disabled" flag tron_testnet_nile's backend and Blockbook dev instance are not currently deployed, so its connectivity/rpc/api tests cannot pass. Rather than delete the test definitions, mark the coin "disabled": true in tests/tests.json and teach every consumer to skip it: - tests/integration.go skips disabled coins with a visible SKIP - tests/openapi/src/config.ts drops disabled coins from e2e selection - .github/scripts/runner.py treats disabled coins as non-deployable Remove the flag to re-enable. Documented in AGENTS.md and covered by Go and Python unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(connectivity): gate backend/node RPC checks behind BB_TEST_BACKEND_CONNECTIVITY The connectivity suite dialed both the raw backend/node RPC (rpc_url) and the Blockbook API for every coin. The node RPC endpoints are only routable from the CI/CD network, so local runs failed on unreachable nodes even when Blockbook itself was healthy. Gate the node RPC checks behind BB_TEST_BACKEND_CONNECTIVITY: off by default (local runs verify Blockbook reachability only), on in CI. The flag is set in the testing.yml connectivity job and the deploy.yml post-deploy connectivity step, forwarded into the build container by the Makefile, and exposed locally via a --backend-connectivity flag on run-integration-tests.sh. Documented in AGENTS.md and covered by a unit test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(connectivity): route Blockbook websocket dial through egress proxy BlockbookHTTPIntegrationTest's HTTP client already honors the proxy via http.ProxyFromEnvironment, but the gorilla websocket.Dialer in BlockbookWSIntegrationTest did not, so the WS check failed to resolve the Blockbook host from behind an egress proxy (where it is only reachable through the proxy). Set Proxy: http.ProxyFromEnvironment on the dialer to match the HTTP client and the OpenAPI e2e suite; a no-op when no proxy is configured. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(ci): resolve build/deploy coin aliases against the context, not cwd resolve_build_selection and resolve_deploy_selection normalized the "_"→"-" coin alias with normalize_coin_name(Path.cwd(), ...), so the underscore form of a hyphenated coin (e.g. ethereum_classic → ethereum-classic) only resolved when the process happened to run from the repo root. Run from any other directory (e.g. the unit tests) the alias was left unresolved and rejected as an unknown coin. Resolve against the already-loaded context.all_coins instead, which is derived from the workspace the context was built from, so selection no longer depends on the working directory. Adds a deploy-side regression test alongside the existing build one. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(integration): drop fiat-rate e2e tests for ETH testnets (no price feed) ethereum_testnet_sepolia and ethereum_testnet_hoodi disable fiat rates in configs/coins (fiat_rates-disabled instead of fiat_rates), because valueless testnet ETH has no CoinGecko feed — the rate downloader never runs. The WsGetCurrentFiatRates e2e test therefore hard-failed with "No tickers found\!", and GetCurrentFiatRates/GetTickersList/GetMultiTickers/WsGetFiatRatesForTimestamps/ WsGetFiatRatesTickersList only ever skipped. Remove the six fiat-dependent tests from both testnet entries; the non-fiat GetBalanceHistory/WsGetBalanceHistory stay. Mainnet ethereum (fiat enabled) and tron_testnet_nile (fiat enabled via mainnet TRX's CoinGecko id) keep them. Verified: OpenAPI e2e now passes for both coins (54 ok, 4 unrelated skips, 0 fail). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(e2e): cover GetContractInfoNonVaultEVM on ethereum_testnet_sepolia Add an OpenAPI fixtures file for Sepolia with two canonical, permanently deployed ERC20s — Chainlink LINK (0x7798…4789) and Circle USDC (0x1c7D…7238) — and enable GetContractInfoNonVaultEVM for the coin. The test GETs /api/v2/contract/<addr>?protocols=erc4626 and asserts the contract resolves and is NOT mis-flagged as an ERC4626 vault (the strict opt-in gate). Both addresses were verified indexed on the deployed Sepolia Blockbook (correct symbol/decimals, protocols absent); e2e passes (29 ok, 1 unrelated skip, 0 fail). Not added for ethereum_testnet_hoodi: that testnet has no token ecosystem indexed, so there is no stable contract to anchor a fixture. The remaining EVM contract/protocol/ERC4626 tests still require curated on-chain vault and holder fixtures that do not exist on these testnets. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(ci): harden testnet test plumbing after review Follow-up hardening surfaced by a deep review of the testnet test work; no behavior change on the happy path. - deploy_plan.build_connectivity_regex: fail closed on an empty name list. An empty "()" alternation matches the empty string, so `go test -run` would select EVERY connectivity subtest instead of none. The caller already filters to a non-empty set; this makes the deploy-gating helper safe on its own. - runner_test: pin canonical_coin_name's check ordering so underscore-native coins (e.g. base_archive, ethereum_testnet_sepolia) are returned unchanged rather than rewritten to a hyphen variant — a reorder regression would otherwise stay green. - config.ts: document the "disabled" stay-in-sync contract on the actual filtering logic (it previously lived only on the types.ts declaration) and explain why the explicit-OPENAPI_COINS guard is needed alongside the filter. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
… convention Token transfer / token balance responses dropped the `decimals` field whenever it was 0 (the JSON tag carried `,omitempty`), so clients could not distinguish a genuine 0-decimal token from missing metadata and had to guess (trezor-suite defaults to 18). See trezor#1577. - Remove `,omitempty` from api.Token.Decimals and api.TokenTransfer.Decimals so the field is always present (matches the existing ContractInfoResult). - In getContractDescriptorInfo, when a contract's metadata cannot be read on-chain, fall back to the coin's default decimals (18 for ERC-20) instead of surfacing/persisting an ambiguous 0. Genuinely 0-decimal tokens always carry a resolved (handled) standard, so they keep their 0. - Mirror the always-present field into blockbook-api.ts and mark decimals required in openapi.yaml for Token and TokenTransfer (parity typecheck). - Add a regression test asserting decimals is serialized even when 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add assertTokenDecimals and wire it into GetAddressTokensEVM (Token) and GetTransactionEVMShape (TokenTransfer), making the trezor#1577 expectation explicit on top of the schema's `required: decimals`. The check reuses already-fetched responses (no extra requests), runs on all EVM coins, and additionally enforces a non-negative integer, which the schema does not. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The REST rate limiter only wrapped routes under /api*, so the HTML explorer pages (/address/, /xpub/, /tx/, /search/, …) bypassed it entirely — even though they call the same expensive backend as the API (GetAddress, GetXpubAddress). A flood of /address/<addr> requests was neither throttled nor counted by the limiter. Replace the /api-only allowlist with a deny-all-except-static gate (isRateLimitedRoute): every dynamic public route under the server base path is now limited under one shared per-client budget, and only static assets, api-docs, the OpenAPI spec, and the WebSocket endpoint are exempt. WebSocket must stay exempt because its handler blocks for the whole connection lifetime and has its own limiter. New routes are covered automatically. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rage Now that the limiter covers both the explorer UI and the REST API, the REST_ naming is misleading. Rename throughout: - env vars: <NET>_REST_* -> <NET>_REST_UI_* (the unrelated <NET>_REST_BALANCE_HISTORY_MAX_TXS is left untouched) - Go identifiers: restAPI*/RestAPI* -> restUI*/RestUI* - Prometheus metrics: blockbook_rest_api_* -> blockbook_rest_ui_* - docs/env.md and Grafana panels updated accordingly No backward-compat aliases: the limiter is unreleased (on master, not in v0.5.0), so the old names never shipped. Existing dashboards/alerts referencing blockbook_rest_api_* must move to blockbook_rest_ui_*. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
isRateLimitedRoute exempted any path with the "api-docs" prefix, so a
request like /api-docsx bypassed the limiter and fell through to the
explorer index handler unthrottled. Match the registered routes exactly
("api-docs" and "api-docs/...") instead, mirroring the other exemptions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The limiter panels' titles, help, and metric names already moved to the "Public HTTP" / rest_ui naming when the limiter was extended to cover the explorer UI; their x-panel-key join keys were left as rest_api. Rename the three limiter panels (rejections, active_ips, max_active_per_ip) to rest_ui.* in both template.json and panels.yaml. The rest_api.requests and rest_api.balance_history_* panels describe REST API endpoint traffic and keep their keys. render_grafana.py --check passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reduce the default per-client REST/UI limits to clamp abusive traffic more tightly: rate limit 600->180 req/min (3 req/s), burst 120->40, max-concurrent 24->12. Still overridable per network via the <NET>_REST_UI_* env vars; update docs/env.md to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
isRateLimitedRoute assumed basePath always ends in "/", but splitBinding
keeps a "-public=:port/path" binding verbatim (e.g. "/bb"). With such a
base path, TrimPrefix left a leading slash on rel ("/favicon.ico"), so the
deny-list missed and static assets, favicon, api-docs and openapi.yaml were
incorrectly rate-limited while dynamic routes stayed covered. Trim any
leading slash so the suffix matches in either binding shape, and cover the
slash-less base path in TestRestUIRouteMatching.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The defaults-lowering commit updated the code and docs/env.md to 180/40/12 but not the Grafana panel descriptions, which still told operators the budget was 600/min, burst 120, concurrency cap 24. render_grafana.py --check does not validate description prose, so the drift went unnoticed. Sync the rest_ui.rejections and rest_ui.max_active_per_ip descriptions to 180/40/12. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The RestAPI->RestUI field rename left the four limiter fields one space short of the struct's gofmt tag-alignment column, so `gofmt -l` flagged the file. Re-align; whitespace only, no behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The REST/UI limiter deny-list also exempts /test-websocket.html, but the exemption list omitted it. Add it. Also reword the "Despite the REST_ prefix" caveat, which no longer fits now that the variables are named REST_UI_* and already advertise UI coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The rename of the env vars to REST_UI_* and the lowered 180/40/12 defaults were verified only by the build, not by any assertion. Add a readRestUILimiterConfig test that locks the lowered defaults, checks each REST_UI_* override, and asserts the zero-burst validation error. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* feat(syscoin): port Syscoin support to latest upstream Reapply Syscoin SPT parsing, indexing, API, explorer, packaging, and test fixtures on top of current upstream Blockbook so the fork can review Syscoin-specific changes separately from the main replacement. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): forward mempool asset and send option wrappers Keep Syscoin asset mempool lookups indexed through BaseMempool and forward both asset lookup and optional sendrawtransaction parameters through upstream metrics wrappers. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): stabilize asset paging and block hash lookups Sort Syscoin asset search results before paging and preserve upstream header lookup behavior when blocks are requested by hash without a known height. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): verify testnet backend artifacts Add the Syscoin 5.1 release checksum signature metadata to the testnet backend config so the upstream artifact lint accepts both default and arm64 downloads. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(syscoin): inherit upstream block lookup Remove the Syscoin GetBlock override now that the embedded BitcoinRPC already uses the Syscoin parser and upstream header lookup behavior. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): preserve asset metadata in mempool filters Carry indexed SPT asset metadata through mempool input lookups and mark asset-mask filtered histories as unknown-sized for paging. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): address latest asset and proof review issues Return SPV proof payloads without double encoding, preserve asset masks in explorer paging, treat asset-mask address histories as filtered, and keep registry precision for ERC20 assets. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): return SPV proof as raw JSON Carry syscoingetspvproof results as json.RawMessage so object proofs are returned without string escaping. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): keep SPT ERC20 display precision Restore 8-decimal display precision for ERC20-backed Syscoin assets because SPT amounts are indexed as Syscoin CAmount values. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): retry fallback assets and expose mempool input metadata Retry NEVM metadata when cached asset placeholders are encountered and include SPT input metadata in mempool websocket transaction conversion. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): preserve parsed block parents and cap asset pages Preserve previous block hashes for Syscoin raw block parsing and keep asset history responses bounded when mempool rows are prepended. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): reject unknown NEVM assets and preserve asset masks Avoid caching fabricated NEVM asset metadata for unsupported registry entries and keep Syscoin assetMask filters on address pagination links. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): normalize asset value strings and mempool deltas Keep asset valueStr numeric-only and compute unconfirmed asset balances from both mempool outputs and inputs. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): expose asset symbols for tx details Keep assetInfo valueStr numeric while exposing asset symbols separately for transaction detail display. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): prioritize exact asset search and preserve paging Resolve exact numeric asset searches before fuzzy matches and page asset histories over mempool plus confirmed transactions without skipping confirmed rows. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): handle asset search and paging edge cases Resolve numeric asset GUID searches before block-height redirects and avoid confirmed asset history fetches when a page is filled by mempool entries. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): normalize template shortcut checks Use the shared Syscoin shortcut helper in templates so testnet tSYS renders Syscoin-specific UI controls. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): bound NEVM calls and avoid asset cache pollution Apply configured RPC timeouts to NEVM metadata calls and use non-caching RocksDB read options for full asset cache scans. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): record NEVM metadata errors in metrics Pass FetchNEVMAssetDetails errors through the metrics wrapper so failed metadata RPC calls are observable. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): assign unique testnet ports Move Syscoin testnet to an unused port block so it no longer collides with bgold testnet services. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): avoid NEVM port collision Move Syscoin's managed NEVM HTTP endpoint off Tron's shared port and size the asset transaction-count VLQ buffer for the full encoded range. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): add lowercase asset tx count alias Expose lowercase txs on asset-search rows while preserving the legacy Txs field for existing Syscoin clients, and document the intentional 8-decimal UTXO asset formatting. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): use lowercase asset search tx count Keep asset-search transaction count consistent with the rest of the API by exposing only the lowercase txs field. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): propagate asset parse failures Return SPT allocation decode errors from Syscoin transaction and block parsing so malformed asset transactions cannot be indexed without AssetInfo. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): reject malformed asset payloads Validate SPT OP_RETURN pushdata lengths and allocation output indexes so malformed asset transactions return parser errors instead of panicking. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(syscoin): omit SYSX zero contract Keep the built-in SYSX asset contract empty so native SYSX does not expose or link to the zero NEVM address while preserving canonical metadata. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: jagdeep sidhu <sidhujag@syscoin.org> Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(syscoin): restore explorer UX after upstream merge Preserve Syscoin explorer surfaces on the upstream-latest base and keep shared templates guarded so non-Syscoin explorers continue to render correctly. Co-authored-by: Cursor <cursoragent@cursor.com> * Update public.go --------- Co-authored-by: jagdeep sidhu <sidhujag@syscoin.org> Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0722016323
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if !hasConnectivity(cfg) { | ||
| continue |
There was a problem hiding this comment.
Do not drop rpc/sync-only integration tests
When make test-integration or a narrow run such as TestIntegration/dash=main/rpc is used, this filter prevents any coin entry without a connectivity key from getting a top-level subtest at all. I checked tests/tests.json, and many still-valid rpc/sync entries (for example bcash_testnet, dash, ecash, firo, zcash_testnet) have no connectivity, so CI's new Run integration tests step silently stops exercising them instead of running their rpc/sync suites.
Useful? React with 👍 / 👎.
| e2e_names.append(matchable_name(lookup_coin)) | ||
| test_coins.append(lookup_coin) |
There was a problem hiding this comment.
Keep deploy tests pointed at the requested config
For deploys of configs that set coin.test_name (for example base_archive maps to base but has a different Blockbook port/package), these outputs switch post-deploy checks to the test name instead of the requested config. The workflow then waits/tests base via test_coins_csv and TestIntegration/base=main rather than the just-deployed base_archive, so an archive deploy can pass while its own Blockbook instance was never checked.
Useful? React with 👍 / 👎.
Summary
mastercontents with the currentupstream-latesttree.upstream-latestin the ancestry somasteris no longer behind it after merge.Test plan
origin/masterand includesorigin/upstream-latestancestry.origin/upstream-latestbefore committing.Made with Cursor