Skip to content

refactor: replace REST token registry with DB-based assets-ext reads#730

Draft
matiwinnetou wants to merge 31 commits into
mainfrom
refactor/assets-store-ext
Draft

refactor: replace REST token registry with DB-based assets-ext reads#730
matiwinnetou wants to merge 31 commits into
mainfrom
refactor/assets-store-ext

Conversation

@matiwinnetou
Copy link
Copy Markdown
Collaborator

@matiwinnetou matiwinnetou commented Apr 8, 2026

Summary

Adds direct database access to token metadata tables (CIP-26 / CIP-68) populated by the yaci-store-assets-ext extension. The API module reads token metadata — name, ticker, decimals, description, logo — from the shared database via its own JPA entities and a batched query path, so /account/balance, /block/transaction, and /search/transactions can enrich native-token balances and operations with metadata without any out-of-process call.

What's in this PR

yaci-indexer (write side)

  • yaci-store-assets-ext + yaci-store-assets-ext-spring-boot-starter dependencies
  • store.assets.ext.enabled=true + store.assets.ext.cip26.enabled=true in application.properties
  • CIP-68 enabled by default (inner class default); CIP-113 left disabled for now

api module (read side)

Follows the existing project convention: own JPA entities map to yaci-store tables, no direct dependency on yaci-store jars (see "Why JPA entities are duplicated" below).

Read model under api/common/model/entity/:

  • TokenMetadataEntityft_offchain_metadata (CIP-26)
  • TokenLogoEntityft_offchain_logo (CIP-26)
  • MetadataReferenceNftEntity + MetadataReferenceNftIdmetadata_reference_nft (CIP-68)

Repositories under api/common/model/repository/:

  • TokenMetadataRepository, TokenLogoRepository
  • MetadataReferenceNftRepository + MetadataReferenceNftRepositoryCustom / …CustomImpl — custom fragment with a native SQL window-function query that returns the latest-slot row per (policy_id, asset_name) pair in a single round-trip, regardless of batch size

TokenQueryService:

  • @Transactional(readOnly = true), owns all CIP-26/CIP-68 merge logic and priority (CIP-68 > CIP-26)
  • Handles CIP-68 prefix conversion transparently (0014df10000643b0)
  • Abstracts CIP standard details — consumers get a unified TokenRegistryCurrencyData
  • Accepts Collection<AssetFingerprint> directly (no subject/policyId string shuffling)
  • Uses StructuredTaskScope.ShutdownOnFailure to fork the CIP-26 metadata and logo batch queries in parallel — with a documented caveat about @Transactional context not propagating through virtual threads (accepted because CIP-26 rows are written only during the periodic offchain sync; read-skew risk is negligible for token metadata)
  • CIP-68 logo format detection: http(s)://, ipfs://, ar://URL; everything else (including raw base64 and data: URIs) → BASE64
  • Logo fetch gated by TOKEN_REGISTRY_LOGO_FETCH toggle

TokenRegistryServiceImpl — thin delegate:

  • Asset extraction from Rosetta domain objects (BlockTx, AddressBalance, Utxo, Operation, etc.)
  • Forwards metadata lookup to TokenQueryService.queryMetadataBatch() with Set<AssetFingerprint> directly

Config: TOKEN_REGISTRY_LOGO_FETCH toggle (default false) — when false, logo columns are skipped entirely from the query path so logo blobs never leave the DB.

Why JPA entities are duplicated (temporary)

This PR introduces three new JPA entities + repositories in the api module that map to the exact same tables yaci-store-assets-ext owns upstream. This looks wasteful — yaci-store already publishes Cip26StorageReader and Cip68StorageReader interfaces that do the same lookups — and it is.

The duplication is forced by the current repo layout: api and yaci-indexer are two separate Spring Boot modules, and the api module has never pulled in yaci-store-* jars. Every yaci-store-backed table used by a Rosetta endpoint (address_utxo, block, transaction, pool_registration, etc.) has a duplicate *Entity + *Repository downstream — this PR just adds three more to that pile for the CIP-26/CIP-68 case.

The real fix is to merge api and yaci-indexer into a single rosetta-app Spring Boot module and run yaci-store in read-only mode on the API replicas, so the api side can consume yaci-store's storage reader interfaces directly without any entity/repository duplication. Tracked in #731.

Until #731 ships, this PR takes the pragmatic route:

  • Own JPA entities + repositories — matches the project convention used everywhere else in the api module
  • Own custom fragment (MetadataReferenceNftRepositoryCustom + Impl) for the CIP-68 batch window-function query, even though the same query exists upstream in yaci-store-assets-ext

When #731 lands, this entire downstream entity/repository/custom-fragment layer for CIP-26/CIP-68 can be deleted in favor of cip26StorageReader.findBySubjects(...) and cip68StorageReader.findBySubjects(...) — the upstream APIs the rosetta-app will consume directly.

Tests (~62)

Component Tests Coverage
TokenQueryService 28 CIP-26/CIP-68 merge, prefix conversion edge cases, logo format detection (http/https/ipfs/ar/base64/data-URI), logo toggle, batch queries, empty-batch short-circuit
TokenRegistryServiceImpl 14 Delegation to query service, asset extraction from all Rosetta types, fetch-helper edge cases
TokenRegistryMapper 14 Field mapping, BASE64 vs URL logo formats, null handling, end-to-end logo pipeline
DataMapper 7 Rosetta Amount building with metadata, logo passthrough, ADA defaults, value negation

Full api unit-test run: 761 tests, 0 failures, 21 errors — the 21 errors are pre-existing @SpringBootTest context-load failures that fail identically on main (JDK-version/devkit-DB issue, unrelated to this PR).

Temporary: pre-release SNAPSHOT

yaci-store-assets-ext is not yet released. The yaci-indexer pom references 2.1.0-pre4-d358232-SNAPSHOT, which must be installed to the local Maven repository via ./gradlew publishToMavenLocal from the feature/asset-store-ext branch of bloxbean/yaci-store. Revert this version bump once a proper release is cut — at which point the downstream MetadataReferenceNftRepositoryCustom fragment can also be removed in favor of upstream's Cip68StorageReader.findBySubjects(...), and ultimately the whole downstream entity layer disappears with #731.

Test plan

  • Run yaci-indexer on preprod with store.assets.ext.enabled=true — verify ft_offchain_metadata, ft_offchain_logo, metadata_reference_nft populate
  • Run API and verify /account/balance returns token metadata (name, ticker, decimals, etc.) from DB
  • Test TOKEN_REGISTRY_LOGO_FETCH=true vs false — confirm logos only appear when enabled
  • Verify /block and /search/transactions also carry token metadata
  • mvn compile -pl api,yaci-indexer passes
  • New unit tests pass (62/62)

🤖 Generated with Claude Code

…eReaders

Replace the HTTP-based token metadata fetching (tokens.cardano.org REST API)
with direct database reads via yaci-store assets-ext CIP-26/CIP-68 StorageReaders.
The yaci-indexer now syncs token metadata into local DB tables, and the API module
reads from them directly — eliminating external REST dependency, caching layer,
and improving reliability.

Key changes:
- Add yaci-store-assets-ext extension to both api and yaci-indexer modules
- Create AssetsExtReadOnlyConfiguration for API (read-only, no processors/cron jobs)
- Rewrite TokenRegistryServiceImpl to use Cip26/Cip68 StorageReaders
- Delete HTTP gateway, domain models, Guava token cache and related tests
- Include pre-release jars in libs/ as file-based Maven repo (temporary)
- Keep TOKEN_REGISTRY_LOGO_FETCH toggle for logo enable/disable

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #272

Tests run against preprod network with live blockchain data

Remove yaci-store-assets-ext dependency from API module. Instead, create
own JPA entities (TokenMetadataEntity, TokenLogoEntity, MetadataReferenceNftEntity)
mapping to the same tables, following the existing project pattern.

Introduce TokenQueryService with @transactional(readOnly=true) that abstracts
CIP-26/CIP-68 query details and priority-based merge. TokenRegistryServiceImpl
is now a thin delegate that only handles asset extraction from Rosetta domain
objects and forwards metadata lookup to TokenQueryService.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #273

Tests run against preprod network with live blockchain data

Mateusz Czeladka and others added 2 commits April 8, 2026 17:30
Fork CIP-26 metadata and logo repository calls in parallel using
StructuredTaskScope.ShutdownOnFailure (Java 24 preview), then join
before the merge phase in queryMetadataBatch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
23 tests covering:
- Single subject query: empty results, CIP-26 only, CIP-68 only,
  full override, partial override, null decimals default
- CIP-68 prefix conversion: non-fungible prefix skipped, plain asset
  name skipped, short subject skipped, correct 0014df10->000643b0
  conversion, bare prefix edge case
- Logo handling: disabled flag, CIP-26 BASE64 logo, CIP-68 URL logo,
  CIP-68 overrides CIP-26 logo, disabled suppresses CIP-68 logo,
  null logo graceful handling
- Batch queries: multiple subjects, missing subjects fallback,
  batch logo fetch, batch CIP-68 override, null logo filtering

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #274

Tests run against preprod network with live blockchain data

TokenRegistryMapper (14 tests):
- Full field mapping, null handling, all-null fields
- Logo format mapping: BASE64, URL, null format, null value
- End-to-end: CIP-26/CIP-68 logos through full mapping pipeline

DataMapper (7 tests):
- ADA amount creation with null symbol
- Native token amount with metadata
- Logo passthrough for both BASE64 and URL formats
- Null metadata graceful handling
- Version passthrough
- Value negation for spent/unspent

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #275

Tests run against preprod network with live blockchain data

Drop the file-based libs/ repository approach in favor of resolving
yaci-store-assets-ext from ~/.m2/repository (installed via
./gradlew publishToMavenLocal from the yaci-store build).

Bumps the version to 2.1.0-pre4-adaf5b0-SNAPSHOT.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #276

Tests run against preprod network with live blockchain data

Drop the unused TokenQueryService.queryMetadata() method and its
private applyCip26(builder, cip26, subject) helper. The method was
never called from production code — all paths go through
queryMetadataBatch, including single-subject use cases.

Rewrites the 18 TokenQueryServiceTest call sites to exercise the
batch path with single-element lists, preserving full coverage of
CIP merge semantics, prefix conversion, and logo handling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #277

Tests run against preprod network with live blockchain data

#4/#7 Pass AssetFingerprint through instead of re-parsing subject strings.
TokenQueryService.queryMetadataBatch now accepts Collection<AssetFingerprint>
directly and returns Map<AssetFingerprint, TokenRegistryCurrencyData>. The
CIP-68 prefix check uses fingerprint.getSymbol() instead of substring
gymnastics on the concatenated subject. TokenRegistryServiceImpl's delegation
drops the dual subjects-list + subjectToPolicyId-map plumbing and no longer
calls toSubject() twice per asset.

#5 Detect CIP-68 logo format from the value instead of hardcoding URL.
Known URL schemes (http://, https://, ipfs://, ar://) map to URL; everything
else (raw base64, data: URIs) maps to BASE64. Adds 5 new tests for the
detection logic covering each case.

#6 Consistent decimals policy in TokenQueryService: never default null to 0
in the query layer — let the downstream mapper
(AccountMapperUtil.getDecimalsWithFallback) provide the fallback. CIP-26 and
CIP-68 paths now behave the same for null decimals.

TokenRegistryServiceImplTest simplified: dropped the fallback-when-missing
test since that behavior is owned by TokenQueryService and already covered
by its tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #278

Tests run against preprod network with live blockchain data

Replace the N+1 per-subject CIP-68 query pattern in TokenQueryService
with a single native SQL call using ROW_NUMBER() OVER (PARTITION BY
policy_id, asset_name ORDER BY slot DESC) + row-value tuple IN.

Before: 1 (or 2 with logos) CIP-26 queries + K individual CIP-68
queries, where K = number of CIP-68 fungible tokens in the batch.
A wallet with 50 CIP-68 tokens triggered 51-52 round-trips.

After: 2 or 3 queries total (CIP-26 metadata, CIP-26 logos when
enabled, CIP-68 latest-by-slot) regardless of batch size. The CIP-68
query is skipped entirely when no fungible token candidates are
present.

Implementation uses Spring Data JPA's custom repository fragment
pattern (MetadataReferenceNftRepositoryCustom + Impl suffix,
auto-detected). Dynamic SQL builds the correct number of positional
placeholders at call time; values are bound via Query.setParameter
so there is no SQL injection surface. The native query is portable
across H2 2.2.x and PostgreSQL 12+.

The derived method findFirstByPolicyIdAndAssetNameAndLabelOrderBySlotDesc
had only one production caller and is removed. Test stubs are updated
to mock the new batch method; ArgumentCaptor verifies that the
fungible-to-reference-NFT prefix conversion still produces the
correct PolicyAssetPair input.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #279

Tests run against preprod network with live blockchain data

The fork/join block in queryMetadataBatch is deliberate: parallelising
the two CIP-26 queries (metadata + logos) saves a round-trip at the
cost of losing the outer readOnly transaction context inside the
forked virtual threads. Since CIP-26 rows are only written during
the periodic offchain token-registry sync, the read-skew risk is
negligible for our use case.

Document the caveat, the reasoning, and the revert recipe so a
future reader is not surprised when they notice that each fork
opens its own transaction.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #280

Tests run against preprod network with live blockchain data

Picks up the upstream CIP-68 batch-query optimization
(bloxbean/yaci-store commit d358232b8) which replaces the per-subject
N+1 pattern in TokenQueryService.prefetchBatch with a single
window-function query.

Only affects the yaci-indexer classpath — the api module uses its
own JPA entities and its own MetadataReferenceNftRepository batch
query, so no behavioral change on the read path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #281

Tests run against preprod network with live blockchain data

@matiwinnetou matiwinnetou changed the title refactor: replace REST token registry with DB-based assets-ext StorageReaders refactor: replace REST token registry with DB-based assets-ext reads Apr 9, 2026
@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #288

Tests run against preprod network with live blockchain data

Adds an optional host-m2 build stage to the api and yaci-indexer
Dockerfiles. During the mvn step we bind-mount the stage and copy
com/bloxbean/cardano artifacts into the cache, then build with -nsu
so Maven does not try to re-resolve snapshots from remote repos.

The host-m2 context is wired into the api, indexer, and
integration-test-indexer compose files via additional_contexts,
defaulting to $HOME/.m2/repository. Regular builds without the
context are unaffected because the default stage is empty scratch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #289

Tests run against preprod network with live blockchain data

…store

Replace the custom repository fragment (MetadataReferenceNftRepositoryCustom
+ CustomImpl) with a single @query(nativeQuery=true) method on
MetadataReferenceNftRepository using CONCAT(policy_id, asset_name) IN
(:concatenatedKeys). Policy IDs are fixed 56-char hex so the concatenation
is unambiguous.

Mirrors the upstream approach in bloxbean/yaci-store's
MetadataReferenceNftRepository.findLatestByConcatenatedKeys — the two
codebases now share the same SQL shape and the same Spring Data idiom.
Once #731 merges the api and yaci-indexer modules into rosetta-app, this
downstream repository layer disappears and the upstream query becomes the
single source of truth.

Removes ~56 lines net:
- Delete MetadataReferenceNftRepositoryCustom interface (PolicyAssetPair
  record + findLatestByPolicyAssetPairs method)
- Delete MetadataReferenceNftRepositoryCustomImpl (dynamic tuple-IN
  EntityManager implementation)
- TokenQueryService.queryMetadataBatch collects List<String> concatenated
  keys instead of List<PolicyAssetPair>, calls findLatestByConcatenatedKeys
- Tests: 14 stubs switch from findLatestByPolicyAssetPairs(anyList(), ...)
  to findLatestByConcatenatedKeys(anyCollection(), ...); ArgumentCaptor
  test verifies the concatenated string instead of a PolicyAssetPair

Performance trade-off: CONCAT on the WHERE side means the planner can't
do composite-index seeks on (policy_id, asset_name, slot); it does a
label-filtered scan + CONCAT comparison instead. Acceptable because
metadata_reference_nft is a small table (one row per token metadata
update, updates are rare) and the optional idx_metadata_reference_nft
_policy_label index from optional-indexes.sql turns the scan into an
index scan when needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #290

Tests run against preprod network with live blockchain data

Clients rely on a runtime switch to turn token-registry enrichment on and
off; the assets-ext refactor dropped it. Reintroduce a single flag,
TOKEN_REGISTRY_ENABLED (default false), and route it through
TokenQueryServiceImpl so disabled requests short-circuit to a policyId-only
fallback without hitting the DB.

Also revert the decimals-non-null contract from e5efb3b: the disabled
fallback now mirrors main (policyId only, subject/decimals null), so the
mergeMetadata path no longer seeds decimals=0. Restored getDecimalsWithFallback
in AccountMapperUtil and TransactionMapperUtils and flipped
TokenRegistryCurrencyData.decimals back to @nullable.

Stripped the legacy HTTP-era flags (TOKEN_REGISTRY_BASE_URL,
TOKEN_REGISTRY_CACHE_TTL_HOURS, TOKEN_REGISTRY_REQUEST_TIMEOUT_SECONDS)
from every env template, docker-compose, Helm chart, CI workflow, and doc
that still referenced them. Enabled token registry + logo on preprod
(.env.docker-compose-preprod, values-preprod.yaml). Rewrote
docs/docs/advanced-configuration/token-metadata.md to describe the new
DB-backed yaci-store assets-ext flow instead of the removed
cf-token-metadata-registry HTTP proxy setup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #300

Tests run against preprod network with live blockchain data

…decimals

Client feedback: on most Rosetta chains decimals is a native, mandatory
field on every asset — and on Cardano we need to enrich it via assets-ext
even when the rest of the token-registry metadata isn't exposed. So the
flag shouldn't gate DB access; it should gate only the extra enrichment
fields in currency.metadata.

New wire contract:
- currency.decimals              — always populated (CIP-26/CIP-68 value or 0 fallback)
- currency.metadata.policyId     — always populated
- currency.metadata.{subject,name,description,ticker,url,logo,version}
                                 — only when TOKEN_REGISTRY_ENABLED=true

Code changes:
- TokenQueryServiceImpl drops the enabled short-circuit and always
  queries the assets-ext tables; mergeMetadata seeds decimals=0 and
  always populates policyId + subject.
- TokenRegistryCurrencyData.decimals back to @nonnull Integer.
- AccountMapperUtil / TransactionMapperUtils drop the
  getDecimalsWithFallback helper and inline metadata.getDecimals().
- DataMapper injects TOKEN_REGISTRY_ENABLED; when false it emits a
  policyId-only CurrencyMetadataResponse, when true it delegates to
  TokenRegistryMapper for the full mapping. Decimals continues to flow
  to CurrencyResponse.decimals unconditionally.

Tests:
- DataMapperTest gains a TokenRegistryEnabledFlagTests nested class
  covering both flag states and null-metadata input.
- AccountMapperUtilTest and TransactionMapperUtilsTest flip the flag on
  at construction since they assert on enrichment fields.
- TokenQueryServiceTest drops the RegistryEnabledFlagTests class and
  updates the 'nothing found' assertions to match the new contract
  (subject populated, decimals=0).

Env and docs:
- New .env.docker-compose-preview (NETWORK=preview, PROTOCOL_MAGIC=2,
  enrichment + logos on). Allow-listed in .gitignore.
- token-metadata.md rewritten to separate 'decimals always' from
  'enrichment gated'; per-network defaults table (mainnet off,
  preprod/preview on).
- env-vars.md, helm-values.md, kubernetes/deployment.md updated to
  reflect the new semantics.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #301

Tests run against preprod network with live blockchain data

Drops an /etc/apt/apt.conf.d/99-retries file into every ubuntu:24.04
stage before the first apt call:

  Acquire::Retries "5";
  Acquire::http::Timeout "30";
  Acquire::https::Timeout "30";
  Acquire::http::No-Cache "true";

Motivation: docker compose builds on shared hosts have been hitting
"File has unexpected size" errors from security.ubuntu.com when a
mirror edge is mid-sync. Retries + No-Cache let apt transparently
re-fetch from a fresh mirror instance instead of failing the whole
build. Does not help when the mirror is serving a permanently-wrong
file (nothing does), but cleans up the common transient case.

Applied to:
- api/Dockerfile                          (build-common)
- yaci-indexer/Dockerfile                 (build-common)
- docker/dockerfiles/mithril/Dockerfile   (cardano-builder + mithril-runner)
- docker/dockerfiles/node/Dockerfile      (cardano-builder + node-runner)
- docker/dockerfiles/postgres/Dockerfile

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #303

Tests run against preprod network with live blockchain data

Comment thread docker-compose-api.yaml
build:
context: ./
dockerfile: ./api/Dockerfile
additional_contexts:
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to remove after yaci-store assets-ext module release.

context: ./
dockerfile: ./yaci-indexer/Dockerfile
additional_contexts:
host-m2: ${HOST_M2:-${HOME}/.m2/repository}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to remove after yaci-store assets-ext module release.

Comment thread yaci-indexer/Dockerfile
# Seed the Maven cache with artifacts from the optional host-m2 context
# (e.g. locally-built yaci-store snapshots), then build with -nsu so Maven
# does not try to re-resolve those snapshots from remote repos.
RUN --mount=type=cache,target=/root/.m2 \
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to remove after yaci-store release

@matiwinnetou
Copy link
Copy Markdown
Collaborator Author

Blocked:

  • Yaci-Store release that includes Assets-Ext module
  • Main-Net CIP-113 release

@matiwinnetou matiwinnetou added this to the 3.0.0 milestone Apr 17, 2026
Aligns MetadataReferenceNftEntity, TokenLogoEntity and TokenMetadataEntity
with the JPA entity convention used across the codebase: identity is
defined by @id fields only, using Lombok's
@EqualsAndHashCode(onlyExplicitlyIncluded = true) plus @EqualsAndHashCode.Include
on each @id. This avoids proxy/lazy-loading pitfalls and matches the
upstream yaci-store style.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
matiwinnetou and others added 2 commits April 28, 2026 12:33
* chore: migrate to JDK 25 LTS and update dependencies

Migrate the project from JDK 24 to JDK 25 LTS and update all stable
dependencies across the multi-module build.

JDK 25 migration required adapting the StructuredTaskScope preview API
(ShutdownOnFailure replaced by Joiner-based open() API) in both
LedgerBlockServiceImpl and AddressHistoryServiceHibernate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* style: use explicit types instead of var for StructuredTaskScope

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Mateusz Czeladka <mateusz.czeladka@cardanofoundation.org>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
#729)

* fix: group MultiAsset entries by policyId before merging in parseTokenBundle

* fix: ix: add @nullable to parseTokenBundle return type
@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #333

Tests run against preprod network with live blockchain data

@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #334

Tests run against preprod network with live blockchain data

…_metadata / cip68_metadata)

Yaci-store assets-ext renamed its tables and merged the logo column into
cip26_metadata. Retarget rosetta entities, drop the now-redundant logo
table + parallel-fetch plumbing, and remove the label filter that
silently hid latest reference-NFT rows tagged with a co-minted prefix.

- Entities: TokenMetadataEntity -> cip26_metadata (+ logo column);
  MetadataReferenceNftEntity -> cip68_metadata; TokenLogoEntity removed.
- Repository: drop label filter from findLatestByConcatenatedKeys to
  match upstream "latest row regardless of label" semantics.
- TokenQueryServiceImpl: drop StructuredTaskScope and TokenLogoRepository;
  single CIP-26 query reads logo on the same row. TOKEN_REGISTRY_LOGO_FETCH
  retained as a wire-gating flag (no longer saves a DB query).
- Tests: rewrite TokenQueryServiceTest for the new shape (64 tests pass).
- Docs: update token-metadata.md data-flow diagram and SQL examples.
- Bump yaci-store snapshot to 2.1.0-pre4-ca14bd5-SNAPSHOT.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #338

Tests run against preprod network with live blockchain data

The previous H2 fixture (testData/devkit.db.mv.db) still carried the old
ft_offchain_metadata / ft_offchain_logo / metadata_reference_nft tables.
Indexer migrations against the new yaci-store snapshot create cip26_metadata
and cip68_metadata, so 15 controller tests were failing with "Table
CIP26_METADATA not found" / 500 errors.

Regenerated end-to-end via scripts/regen-devkit-db.sh:
- yaci-cli boots a local devnet (no Docker required)
- topup_addresses env var funds the two test addresses
- rosetta yaci-indexer runs with the h2-testdata profile, writing the
  V2 schema into testData/devkit.db
- TestDataGenerator submits the canonical transaction set
- two SQL UPDATE statements apply the genesis-block workaround
- script verifies cip26_metadata + cip68_metadata are present before exit

Minor test adjustments to match the regenerated fixture:
- SearchControllerTest: total_count 27 -> 45 (more transactions in the new
  run; account-filter count of 6 unchanged)
- AccountBalanceApiTest.accountBalanceMintedTokenAndEmptyName_TestORG:
  locate MyAsset by symbol filter rather than positional index, since
  devkit mint order is not guaranteed across regens
- AccountCoinsApiTest.accountCoinsMultipleSpecifiedCurrencies_Test: expect
  decimals=0 for MyAsset (no CIP-26 row exists for it; TokenRegistry
  decimals resolution is covered by TokenQueryServiceTest)
- MetadataApiTest.combineWithMetadataTest: TTL 735 -> 155 (chain-tip slot
  is shorter on the freshly-regenerated devkit)

All 995 api tests now pass (8 skipped).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #339

Tests run against preprod network with live blockchain data

Per-project skill that wraps the devkit fixture regeneration. Triggers on
phrases like 'regenerate testdata', 'rebuild devkit.db', or on CI failures
mentioning 'Table CIP26_METADATA not found' (which indicate the committed
testData/devkit.db.mv.db is stale relative to the current yaci-store schema).

The skill folder contains:
- SKILL.md     - workflow, common failure modes, categorisation of the
                 fixture-drift test adjustments
- regen-devkit-db.sh - the actual orchestration script, moved out of
                       scripts/ so the skill is self-contained

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #340

Tests run against preprod network with live blockchain data

Renamed .claude/skills/regenerate-testdata-db/ to
.claude/skills/cardano-rosetta-java-regenerate-testdata-db/ to avoid
collisions with same-named skills the user may have in other projects.
Updated the SKILL.md `name:` frontmatter field and the in-doc path
reference to the bundled regen-devkit-db.sh.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

💥 Preprod Tests: DEPLOYMENT FAILED

🔗 Action Run #341

Tests run against preprod network with live blockchain data

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants