TOC

Oasis June 2025 Engineering update

Wallet and CLI Updates

Wallet

The Wallet team merged 3 PRs this month:

Don't throw on failed debonding transaction (#2187) ±5 by lukaw3d @ 2025-06-03.

e.g. https://wallet.oasis.io/account/oasis1qqazrhk6l3v23nzk098p0dq9xlv5rfkpn50mjxdd
image

CHANGELOG:

Don't throw on failed debonding transaction

Fix screenshots CI (#2186) ±3 by lukaw3d @ 2025-06-03.

Screenshots CI was still broken. https://github.com/oasisprotocol/wallet/actions/workflows/update-screenshots.yml

All causes since #2174:

CHANGELOG:

Fix screenshots CI

In total, 3 pull requests were merged in June.


Cli

The Cli team merged 14 PRs this month:

docs: Document `rofl secret`, `upgrade`, `deploy`, `provider` and minor polishes (#495) ±470 by matevz @ 2025-06-16.

Fixes #479, #480

This PR:

Required by oasisprotocol/docs#1261

feat(cmd/rofl): Add support for machine logs (#492) ±389 by kostko @ 2025-06-23.

Requires at least rofl-scheduler 0.2.0 on the provider side (currently in oasisprotocol/oasis-sdk#2236) with Oasis Core master.

cmd/rofl/build: Validate service volume source (#494) ±304 by abukosek @ 2025-06-20.

Closes #462.

cmd/rofl/deploy: Add --replace-machine flag and show native pricing (#506) ±135 by abukosek @ 2025-06-30.

Closes #487 and #508.

cmd/rofl: Add 'rofl push' command (#502) ±103 by ptrus @ 2025-06-20.

Fixes #498

cmd/rofl/build: Validate image platform and size (#488) ±88 by abukosek @ 2025-06-06.

Closes #416.

cmd: Upgrade oasis-core to 25.3 (#481) ±87 by peternose @ 2025-06-04.

Waiting for client-sdk/go/v0.14.1.

docs: Add --term and --term-count to rofl deploy example (#505) ±52 by matevz @ 2025-06-20.
cmd/rofl/build: Check if service images contain FQDNs (#482) ±35 by abukosek @ 2025-06-02.

Closes #415.

Add Mainnet provider address (#507) ±9 by matevz @ 2025-06-23.

Use Oasis-managed Mainnet ROFL provider by default.

feat(cmd/rofl): Show per-replica metadata (#485) ±8 by kostko @ 2025-06-04.
feat(build/rofl): Bump latest rofl-containers to v0.5.2 (#504) ±2 by kostko @ 2025-06-20.
cmd/rofl/upgrade: Print warning to build, not update (#511) ±2 by matevz @ 2025-06-27.

Fixes #503

cmd/rofl/logs: Add -y for non-interactive mode (#512) ±1 by matevz @ 2025-06-28.

You typically don't encrypt test accounts when developing ROFLs, so the -y flag comes handy in this case to check the logs.

1 new releases of cli were made this month: In total, 14 pull requests were merged in June.


Network Updates

Mainnet highlights

The number of daily transactions on Sapphire Mainnet fluctuated between 10,591 and 137,055. The monthly average in June was 29,754 transactions per day and was 6% lower compared to the last month (31,588 transactions). The daily maximum was 137,055 transactions on 17 June (compared to 122,750 the last month on 16 May).

dateall
2025-06-0110,591
2025-06-0219,286
2025-06-0313,963
2025-06-0413,208
2025-06-0512,122
2025-06-0617,975
2025-06-0720,638
2025-06-0817,940
2025-06-0915,884
2025-06-1019,649
2025-06-1119,698
2025-06-1218,444
2025-06-1312,444
2025-06-1411,596
2025-06-1515,862
2025-06-1673,993
2025-06-17137,055
2025-06-1824,226
2025-06-19128,473
2025-06-2027,408
2025-06-2118,395
2025-06-2212,933
2025-06-2319,379
2025-06-2418,463
2025-06-2516,659
2025-06-26112,841
2025-06-2721,620
2025-06-2812,533
2025-06-2912,599
2025-06-3016,748
2025-07-011,028

The number of daily transactions on Emerald Mainnet fluctuated between 3,257 and 3,852. The monthly average in June was 3,484 transactions per day and was 7% lower compared to the last month (3,730 transactions). The daily maximum was 3,852 transactions on 23 June (compared to 4,396 the last month on 12 May).

dateall
2025-06-013,261
2025-06-023,625
2025-06-033,396
2025-06-043,510
2025-06-053,645
2025-06-063,393
2025-06-073,310
2025-06-083,257
2025-06-093,342
2025-06-103,696
2025-06-113,576
2025-06-123,734
2025-06-133,709
2025-06-143,336
2025-06-153,269
2025-06-163,372
2025-06-173,742
2025-06-183,450
2025-06-193,311
2025-06-203,452
2025-06-213,396
2025-06-223,663
2025-06-233,852
2025-06-243,617
2025-06-253,427
2025-06-263,442
2025-06-273,262
2025-06-283,372
2025-06-293,296
2025-06-303,815
2025-07-01267

{{NODE_STATS mainnet}}

No major outages were reported for Oasis foundation-provided services in June. A few-minutes downtimes were encountered by the ... You can check out the details on the Mainnet status page.

Testnet highlights

[2025-06-20] am3lody:

We have released Oasis Core 25.4 for TESTNET.

Key highlights include: ➡️ Add support for components like the ROFL scheduler to access logs of other components. ➡️ Add support for component label attestation. ➡️ Various minor bug fixes.

Visit the changelog (https://github.com/oasisprotocol/oasis-core/blob/v25.4/CHANGELOG.md) to view all changes. The upgrade is non-breaking and can be performed at any time by replacing the oasis-node binary and restarting your node. All node operators on TESTNET are encouraged to upgrade. For more information and links to releases, see the updated TESTNET network parameters (https://docs.oasis.io/node/testnet/). Thanks!

The number of daily transactions on Sapphire Testnet fluctuated between 8,579 and 24,696. The monthly average in June was 16,352 transactions per day and was 13% lower compared to the last month (18,773 transactions). The daily maximum was 24,696 transactions on 22 June (compared to 46,427 the last month on 11 May).

dateall
2025-06-0115,599
2025-06-0216,867
2025-06-0317,019
2025-06-0418,085
2025-06-0517,437
2025-06-0617,518
2025-06-079,772
2025-06-088,584
2025-06-098,659
2025-06-108,579
2025-06-118,747
2025-06-128,910
2025-06-139,123
2025-06-1417,207
2025-06-1517,192
2025-06-1617,508
2025-06-1717,547
2025-06-1817,844
2025-06-1924,513
2025-06-2018,197
2025-06-2117,861
2025-06-2224,696
2025-06-2316,880
2025-06-2417,255
2025-06-2517,326
2025-06-2617,192
2025-06-2718,776
2025-06-2821,170
2025-06-2921,521
2025-06-3022,982
2025-07-01777

The number of daily transactions on Emerald Testnet fluctuated between 3,017 and 3,287. The monthly average in June was 3,259 transactions per day and was 4% lower compared to the last month (3,390 transactions). The daily maximum was 3,287 transactions on 30 June (compared to 5,619 the last month on 25 May).

dateall
2025-06-013,017
2025-06-023,264
2025-06-033,266
2025-06-043,280
2025-06-053,266
2025-06-063,268
2025-06-073,262
2025-06-083,263
2025-06-093,267
2025-06-103,265
2025-06-113,267
2025-06-123,265
2025-06-133,261
2025-06-143,268
2025-06-153,263
2025-06-163,269
2025-06-173,263
2025-06-183,268
2025-06-193,263
2025-06-203,265
2025-06-213,265
2025-06-223,263
2025-06-233,266
2025-06-243,265
2025-06-253,266
2025-06-263,260
2025-06-273,262
2025-06-283,281
2025-06-293,283
2025-06-303,287
2025-07-01271

{{NODE_STATS testnet}}

No major outages were reported for Oasis foundation-provided services in June. A few-minutes downtimes were encountered by the ... You can check out the details on the Testnet status page.

Oasis Nexus and Explorer

Nexus

The Nexus team merged 34 PRs this month:

analyer/block: Simplify and improve batch processing (#1068) ±332 by ptrus @ 2025-06-26.

In the old code, when the block analyzer was near the head of the chain, the backoff was almost always at 6 seconds.

See retry interval quickly increasing to 6 seconds on a recently started node that is at the head of the chain:

{"analyzer":"sapphire","caller":"block.go:420","height":12287791,"level":"info","mode":"slow-sync","module":"analysis_service","msg":"no data available; will retry","retry_interval_ms":100,"ts":"2025-06-25T08:36:03.901279912Z"}
{"analyzer":"sapphire","caller":"block.go:420","height":12287791,"level":"info","mode":"slow-sync","module":"analysis_service","msg":"no data available; will retry","retry_interval_ms":200,"ts":"2025-06-25T08:36:04.13376454Z"}
{"analyzer":"sapphire","caller":"block.go:420","height":12287791,"level":"info","mode":"slow-sync","module":"analysis_service","msg":"no data available; will retry","retry_interval_ms":400,"ts":"2025-06-25T08:36:04.570368877Z"}
{"analyzer":"sapphire","caller":"block.go:420","height":12287791,"level":"info","mode":"slow-sync","module":"analysis_service","msg":"no data available; will retry","retry_interval_ms":800,"ts":"2025-06-25T08:36:05.403994745Z"}
{"analyzer":"sapphire","caller":"block.go:420","height":12287792,"level":"info","mode":"slow-sync","module":"analysis_service","msg":"no data available; will retry","retry_interval_ms":1440,"ts":"2025-06-25T08:36:07.952763714Z"}
{"analyzer":"sapphire","caller":"block.go:420","height":12287792,"level":"info","mode":"slow-sync","module":"analysis_service","msg":"no data available; will retry","retry_interval_ms":2880,"ts":"2025-06-25T08:36:10.862558227Z"}
{"analyzer":"sapphire","caller":"block.go:420","height":12287794,"level":"info","mode":"slow-sync","module":"analysis_service","msg":"no data available; will retry","retry_interval_ms":4665,"ts":"2025-06-25T08:36:21.879480568Z"}
{"analyzer":"sapphire","caller":"block.go:420","height":12287798,"level":"info","mode":"slow-sync","module":"analysis_service","msg":"no data available; will retry","retry_interval_ms":6000,"ts":"2025-06-25T08:36:46.568709867Z"}
{"analyzer":"sapphire","caller":"block.go:420","height":12287803,"level":"info","mode":"slow-sync","module":"analysis_service","msg":"no data available; will retry","retry_interval_ms":6000,"ts":"2025-06-25T08:37:21.578675488Z"}
{"analyzer":"sapphire","caller":"block.go:420","height":12287810,"level":"info","mode":"slow-sync","module":"analysis_service","msg":"no data available; will retry","retry_interval_ms":5739,"ts":"2025-06-25T08:38:03.155313823Z"}
{"analyzer":"sapphire","caller":"block.go:420","height":12287817,"level":"info","mode":"slow-sync","module":"analysis_service","msg":"no data available; will retry","retry_interval_ms":5490,"ts":"2025-06-25T08:38:43.316051961Z"}

This often caused the analyzers to lag behind the head by 1–2 blocks. There were a couple of reasons for this, so we’ve restructured the code, simplified the logic, and adjusted the backoff behavior for block analyzers.

Summary of changes:

In practice, a failing analyzer should now send queries less frequently (previously every 6 seconds, now up to a 30-second maximum timeout). However, after recovering, or when at the head of the chain, it should resume polling more quickly (every 1 second).

CHANGELOG:

analyer/block: Simplify and improve batch processing

evmabi-backfill: Optimize db queries (#935) ±129 by ptrus @ 2025-06-03.

Fixes #910

TODO:

RuntimeEvmVerifiedContractTxs
                                                                                                QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit  (cost=698040.63..698043.13 rows=1000 width=880) (actual time=134.601..134.607 rows=7 loops=1)
  ->  Sort  (cost=698040.63..698465.63 rows=170000 width=880) (actual time=134.600..134.604 rows=7 loops=1)
        Sort Key: tx.round DESC
        Sort Method: quicksort  Memory: 73kB
        ->  Nested Loop  (cost=0.69..688719.71 rows=170000 width=880) (actual time=95.900..134.496 rows=7 loops=1)
              ->  Seq Scan on evm_contracts  (cost=0.00..854.34 rows=170 width=765) (actual time=0.119..2.820 rows=373 loops=1)
                    Filter: ((abi IS NOT NULL) AND (runtime = 'sapphire'::runtime))
                    Rows Removed by Filter: 10437
              ->  Limit  (cost=0.69..4021.27 rows=1000 width=724) (actual time=0.271..0.352 rows=0 loops=373)
                    ->  Index Scan using ix_runtime_transactions_to_round_abi_parsed_at on runtime_transactions tx  (cost=0.69..85976.66 rows=21384 width=724) (actual time=0.271..0.352 rows=0 loops=373)
                          Index Cond: ((runtime = evm_contracts.runtime) AND (("to")::text = (evm_contracts.contract_address)::text) AND (abi_parsed_at < evm_contracts.verification_info_downloaded_at))
Planning Time: 0.424 ms
Execution Time: 134.690 ms
(13 rows)

RuntimeEvmVerifiedContractEvents
                                                                                                      QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit  (cost=361266.87..361269.37 rows=1000 width=982) (actual time=96.899..97.013 rows=1000 loops=1)
  ->  Sort  (cost=361266.87..361691.87 rows=170000 width=982) (actual time=96.897..96.946 rows=1000 loops=1)
        Sort Key: e.round DESC
        Sort Method: top-N heapsort  Memory: 2049kB
        ->  Nested Loop  (cost=1.25..351945.95 rows=170000 width=982) (actual time=29.907..78.912 rows=27234 loops=1)
              ->  Nested Loop  (cost=0.56..2311.66 rows=170 width=786) (actual time=0.105..8.796 rows=360 loops=1)
                    ->  Seq Scan on evm_contracts  (cost=0.00..854.34 rows=170 width=765) (actual time=0.074..2.877 rows=373 loops=1)
                          Filter: ((abi IS NOT NULL) AND (runtime = 'sapphire'::runtime))
                          Rows Removed by Filter: 10437
                    ->  Index Scan using address_preimages_pkey on address_preimages p  (cost=0.56..8.57 rows=1 width=68) (actual time=0.015..0.015 rows=1 loops=373)
                          Index Cond: ((address)::text = (evm_contracts.contract_address)::text)
              ->  Limit  (cost=0.70..2046.67 rows=1000 width=229) (actual time=0.108..0.187 rows=76 loops=360)
                    ->  Index Scan using ix_runtime_events_abi_parsed_at on runtime_events e  (cost=0.70..250573.28 rows=122471 width=229) (actual time=0.107..0.182 rows=76 loops=360)
                          Index Cond: ((runtime = evm_contracts.runtime) AND ((body ->> 'address'::text) = encode(p.address_data, 'base64'::text)) AND (abi_parsed_at < evm_contracts.verification_info_downloaded_at))
Planning Time: 1.598 ms
Execution Time: 97.192 ms
(16 rows)

CHANGELOG:

evmabi-backfill: Optimize db queries

api/roflmarket: Add api endpoints to fetch specific instance/offer (#1056) ±121 by ptrus @ 2025-06-20.

CHANGELOG:

api/roflmarket: Add endpoints to fetch specific instance/offer
Added `/{runtime}/roflmarket_providers/{address}/instances/{id}` and `/{runtime}/roflmarket_providers/{address}/offers/{id}` api endpoints.

api/rofl_apps: Support ordering by created at (#1077) ±120 by ptrus @ 2025-06-30.

CHANGELOG:

api/rofl_apps: Add support for sorting by creation time
Supports the `sort_by` query parameter:
- `sort_by=created_at`
- `sort_by=created_at_desc`
Example: `GET v1/{runtime}/rofl_apps?sort_by=created_at`

analyzer/runtime: Use events to detect rofl related txs (#1053) ±60 by ptrus @ 2025-06-18.

Fixes: #1051

CHANGELOG:

analyzer/runtime: Use events to detect rofl related txs

api/roflmarket_instances: Support filtering by admin (#1054) ±60 by ptrus @ 2025-06-19.

CHANGELOG:

api/roflmarket_instances: Support filtering by admin address
- The old endpoint `/{runtime}/roflmarket_providers/{address}/instances` has been removed.
- Clients should now use: `/{runtime}/roflmarket_instances?provider={address}` to filter instances by provider address.

storage/roflmarket: Fix roflmarket tables constrains (#1063) ±60 by ptrus @ 2025-06-24.

Fixes #1062 (likely)

Not sure how I missed this in the initial impl.

CHANGELOG:

storage/roflmarket: Fix roflmarket tables constrains

roflmarket: Properly mark removed instances/offers (#1067) ±46 by ptrus @ 2025-06-25.

CHANGELOG:

roflmarket: Properly mark removed instances/offers

storage/roflmarket: Fix double hex-encoded fields (#1040) ±36 by ptrus @ 2025-06-05.

Fixes #1039

CHANGELOG:

storage/roflmarket: Fix double hex-encoded fields

api/roflmarket_instances: Support filtering by deployed app id (#1060) ±33 by ptrus @ 2025-06-23.

CHANGELOG:

api/roflmarket_instances: Support filtering by deployed app id

Changelog 0.7.2 (#1055) ±32 by ptrus @ 2025-06-20.
Changelog 0.6.16 (#1031) ±30 by ptrus @ 2025-06-02.
Changelog 0.7.0 (#1037) ±24 by ptrus @ 2025-06-04.
rofl_instances: Support rofl instance metadata (#1071) ±24 by ptrus @ 2025-06-27.

Initially, rofl apps did not have metadata. Update rofl instances to support metadata and queue refresh of all active rofl apps, so that the instance metadata is fetched.

CHANGELOG:

rofl_instances: Support rofl instance metadata

Add ROFL pools to named accounts (#1049) ±21 by lukaw3d @ 2025-06-17.

CHANGELOG:

Add ROFL pools to named accounts

api/rofl_apps: Support filtering by admin (#1052) ±20 by ptrus @ 2025-06-18.

Fixes #1048

Changelog 0.7.7 (#1075) ±20 by ptrus @ 2025-06-27.
Changelog 0.7.3 (#1058) ±16 by ptrus @ 2025-06-20.
Changelog 0.7.6 (#1069) ±16 by ptrus @ 2025-06-26.
Changelog 0.7.1 (#1045) ±14 by ptrus @ 2025-06-11.
Changelog 0.7.4 (#1061) ±10 by ptrus @ 2025-06-23.
storage/roflmarket_instances: Remove invalid FK (#1064) ±10 by ptrus @ 2025-06-25.
Changelog 0.7.5 (#1066) ±10 by ptrus @ 2025-06-25.
Add epoch index for history.validators (#1032) ±8 by ptrus @ 2025-06-03.

This makes the query ValidatorStakingHistoryUnprocessedEpochs used by validator_history analyzer efficient.

The table and the index are small compared to other tables, so overhead by adding this index is small.

CHANGELOG:

Add epoch index for history.validators

analyzer/consensus: Record timing only for successful requests (#1073) ±8 by ptrus @ 2025-06-27.

This makes it consistent with other (runtime) block analyzers.

CHANGELOG:

analyzer/consensus: Record timing only for successful requests

api/roflmarket_instances: Node id is optional (#1043) ±5 by ptrus @ 2025-06-11.

Fixes: #1041

CHANGELOG:

api/roflmarket_instances: Node id is optional

analyzer/roflmarket: Periodically refresh providers until missing events are added (#1065) ±4 by ptrus @ 2025-06-25.
api/rofl_apps: A bit improved ordering (#1070) ±3 by ptrus @ 2025-06-26.

CHANGELOG:

api/rofl_apps: Prioritize non-removed apps in ordering

rofl_instances: Include instance metadata in rofl app (#1072) ±3 by ptrus @ 2025-06-27.
api/rofl_apps: No active instances for removed apps (#1076) ±3 by ptrus @ 2025-06-30.

"Active instances" are computed by just looking at the expiration epoch. However removed apps don't have any active instances (even if the expiration has not yet expired). So just don't compute active instances for that case. That will also fix the sorting, since currently it can happen that a removed app will show up before non-removed one, due to the misleading "active instances".

CHANGELOG:

api/rofl_apps: No active instances for removed apps

Update oasis-sdk to v0.15 (#1033) ±2 by ptrus @ 2025-06-03.
Update oasis-sdk to include rofl tx fix (#1035) ±2 by ptrus @ 2025-06-04.

Includes: oasisprotocol/oasis-sdk#2230

After the fix is confirmed, tag a new oasis-sdk version and update to that.

Update oasis-sdk to v0.15.2 (#1036) ±2 by ptrus @ 2025-06-04.
openapi: Add roflmarket.ProviderUpdate method (#1047) ±2 by lukaw3d @ 2025-06-14.

CHANGELOG:

openapi: Add roflmarket.ProviderUpdate method

9 new releases of nexus were made this month: In total, 34 pull requests were merged in June.


Explorer

The Explorer team merged 33 PRs this month:

Support flexible searching for multiple words in random order (in all free-text search) (#2012) ±1150 by csillag @ 2025-06-04.

Before this change, we executed all text searches looking for an exact match. So if we searched for "apple pie", it matched "apple pie", but not "apple-pie", and definitely not "pie with apple".

However, Nexus has now (oasisprotocol/nexus#1026) enhanced the search feature for rofl apps and evm tokens to cover these cases, too.

So this PR introduces flexible multi-word searching for all text searches. The search query is tokenized, and we are searching for all of them independently. We have a match if all of them are found, in whatever order.

Here are a few test searched with work with this PR, but didn't work earlier:

For reviewers: I suggest going commit by commit.

CHANGELOG:

Enable flexible multi-word searching in names

Prefer string literals instead of enum constants (#2016) ±770 by csillag @ 2025-06-11.

This is a follow-up to #2002, where @lukaw3d commented:

I somewhat prefer string literals 🤷

So, this PR increases the usage of string literals, instead of Layer and Network constants.

So,

etc.

CHANGELOG:

Prefer string literals instead of constants

Fix detecting production env (fix exhausted type error in production) (#2037) ±752 by lukaw3d @ 2025-06-14.

Fixes #2036
https://explorer.oasis.io/testnet/sapphire/address/oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz

CHANGELOG:

Fix exhausted type error in production (should be a console warning)

Layer handling code cleanup (#2002) ±621 by csillag @ 2025-06-03.

CHANGELOG:

Layer handling cleanup

Migrate build and tests from parcel/jest to vite/vitest (#1975) ±475 by buberdds @ 2025-06-03.

CHANGELOG:

Migrate build and tests from parcel/jest to vite/vitest

Add support for filtering Rofl app list by name (flex search version) (#2013) ±391 by csillag @ 2025-06-11.

This PR is an updated version of #1987, rebased on top of #2012, so that it has the latest multi-word flex search.

See demo of flex search in the Rofl app list here: https://pr-2013.oasis-explorer.pages.dev/testnet/sapphire/rofl/app?name=tg+cha

Original description follows.

===========

The Nexus API has already added support for filtering the Rofl app list by name in oasisprotocol/nexus#997.

In Explorer, currently this is only unitized in the global search since #1973/. (So that we can find Rofl apps from the global search field.)

This PR adds name/based filtering to the Rofl app list page itself.

I suggest reviewing commit by commit, because the different commits add different (small) features, and also there were some preparatory code refactorings, which would otherwise obscure the actual changes.

Screenshots

Filtering the list on the desktop

image

When no match:

image

On mobile:

image

On mobile, vertical mode:

image

No match on mobile:

image

CHANGELOG:

Add support for filtering Rofl app list by name

Improve consensus dashboard resilience (#2004) ±278 by csillag @ 2025-06-04.

Improves #1999

Now a failing query won't collapse the whole consensus dashboard, only the relevant card.
Every card has been split to two component, and the internal parts are now wrapped in the appropriate error boundaries.
The same could be done to the paratime dashboard, too.
Plus, the design could obviously improved, but this already avoids the collapsing of the whole board, so definitely improves the UX.

Before, if any of the queries have a problem:

image

Instead of this, now we get:

Failing to load blocks:

image

Failing to load validators:

image

Failing to load paratimes:

image

Failing to load accounts:

image

Failing to load transactions:

image

Network change proposals: