Skip to content

feat(communities): enables embedding pinned communities in the binary#7562

Merged
jrainville merged 2 commits into
developfrom
feat/pin-status-community
Jun 26, 2026
Merged

feat(communities): enables embedding pinned communities in the binary#7562
jrainville merged 2 commits into
developfrom
feat/pin-status-community

Conversation

@jrainville

@jrainville jrainville commented Jun 17, 2026

Copy link
Copy Markdown
Member

Fixes status-im/status-app#20954

status-app PR: status-im/status-app#21349

This commit adds a production-ready pinned community bootstrap flow so the app can show preloaded communities immediately on first launch, even before network fetches complete. Pinned payloads are now bundled into the binary and used by default, with an optional directory override for local development. The bootstrap is guarded to run only for new profiles, preserving existing data for returning users.

During startup, pinned community payloads are imported through the existing community description handling path, then a non-blocking store-node refresh is triggered per imported community so fresher metadata replaces seeded data shortly after launch. The bootstrap runs asynchronously to avoid delaying app start.

The import flow now also publishes imported communities back to the app through the standard messenger response signal path, so UI state can update immediately instead of waiting for a separate fetch cycle. Tests were added and updated to validate embedded payload loading, database import behavior, and first-run-only semantics, and documentation was updated to describe source precedence and runtime behavior.

For the demo video below, I disabled the normal community fetch that happens when getting the curated communities. This means that only the pinned community mechanism was in use. This simulates store nodes not working.

pinned-community.webm

As you saw in the video, importing the community is quite slow. It takes 35 seconds for me.

So while this work helps in case of store node issues, the Status community is now so big (5MB), that storing it in the DB takes a very long time.

I'll open a new issue to try and find the pain points and hopefully solve them.

@jrainville jrainville requested a review from Copilot June 17, 2026 18:48
@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown

@status-im-auto

status-im-auto commented Jun 17, 2026

Copy link
Copy Markdown
Member

Jenkins Builds

Click to see older builds (66)
Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ 2cd0e7c 1 2026-06-17 18:53:15 ~4 min linux/status-go 📦zip
✔️ 2cd0e7c 1 2026-06-17 18:53:27 ~4 min macos/status-go 📦zip
✖️ 2cd0e7c 1 2026-06-17 18:54:26 ~5 min tests 📄log
✔️ 2cd0e7c 1 2026-06-17 18:58:18 ~9 min windows/status-go 📦zip
✖️ 2cd0e7c 1 2026-06-17 19:04:08 ~15 min tests-rpc-compat 📄log
✔️ 2cd0e7c 1 2026-06-17 19:04:22 ~15 min tests-rpc 📄log
✔️ fd69b75 2 2026-06-17 19:09:51 ~3 min linux/status-go 📦zip
✔️ fd69b75 2 2026-06-17 19:10:20 ~4 min macos/status-go 📦zip
✖️ fd69b75 2 2026-06-17 19:12:23 ~6 min tests 📄log
✔️ fd69b75 2 2026-06-17 19:16:51 ~10 min windows/status-go 📦zip
✖️ fd69b75 2 2026-06-17 19:20:15 ~14 min tests-rpc 📄log
✖️ fd69b75 2 2026-06-17 19:20:41 ~14 min tests-rpc-compat 📄log
✔️ 3e6ddaf 3 2026-06-17 19:37:52 ~4 min macos/status-go 📦zip
✔️ 3e6ddaf 3 2026-06-17 19:38:37 ~5 min linux/status-go 📦zip
✖️ 3e6ddaf 3 2026-06-17 19:41:40 ~8 min tests 📄log
✔️ 3e6ddaf 3 2026-06-17 19:43:16 ~9 min windows/status-go 📦zip
✖️ 3e6ddaf 3 2026-06-17 19:46:34 ~12 min tests-rpc-compat 📄log
✖️ 3e6ddaf 3 2026-06-17 19:51:40 ~18 min tests-rpc 📄log
✔️ 63b6d84 4 2026-06-17 20:18:20 ~4 min linux/status-go 📦zip
✔️ 63b6d84 4 2026-06-17 20:18:36 ~4 min macos/status-go 📦zip
✖️ 63b6d84 4 2026-06-17 20:22:38 ~8 min tests 📄log
✔️ 63b6d84 4 2026-06-17 20:23:21 ~8 min windows/status-go 📦zip
✖️ 63b6d84 4 2026-06-17 20:27:34 ~13 min tests-rpc-compat 📄log
✖️ 63b6d84 4 2026-06-17 20:31:33 ~17 min tests-rpc 📄log
91d1ba5 5 2026-06-19 15:11:48 ~1 min windows/status-go 📄log
✔️ 91d1ba5 5 2026-06-19 15:14:16 ~4 min macos/status-go 📦zip
✔️ 91d1ba5 5 2026-06-19 15:14:22 ~4 min linux/status-go 📦zip
✖️ 91d1ba5 5 2026-06-19 15:19:42 ~9 min tests 📄log
✖️ 91d1ba5 5 2026-06-19 15:26:06 ~16 min tests-rpc 📄log
✖️ 91d1ba5 5 2026-06-19 15:26:56 ~17 min tests-rpc-compat 📄log
✔️ 87dd8aa 6 2026-06-19 19:31:13 ~4 min macos/status-go 📦zip
✔️ 87dd8aa 6 2026-06-19 19:31:17 ~4 min linux/status-go 📦zip
87dd8aa 6 2026-06-19 19:34:31 ~7 min windows/status-go 📄log
✔️ 87dd8aa 6 2026-06-19 19:37:33 ~10 min tests 📄log
✖️ 87dd8aa 6 2026-06-19 19:40:19 ~13 min tests-rpc-compat 📄log
✖️ 87dd8aa 6 2026-06-19 19:44:00 ~17 min tests-rpc 📄log
✔️ 8476e36 7 2026-06-22 15:45:49 ~4 min linux/status-go 📦zip
✔️ 8476e36 7 2026-06-22 15:47:05 ~5 min macos/status-go 📦zip
✔️ 8476e36 7 2026-06-22 15:50:31 ~8 min windows/status-go 📦zip
✔️ 8476e36 7 2026-06-22 15:53:12 ~11 min tests 📄log
✖️ 8476e36 7 2026-06-22 15:56:20 ~14 min tests-rpc-compat 📄log
✖️ 8476e36 7 2026-06-22 15:56:24 ~14 min tests-rpc 📄log
✔️ 4c74c55 8 2026-06-22 16:02:05 ~4 min linux/status-go 📦zip
✖️ 4c74c55 8 2026-06-22 16:06:10 ~8 min tests 📄log
✔️ 4c74c55 8 2026-06-22 16:06:26 ~8 min macos/status-go 📦zip
✔️ 4c74c55 8 2026-06-22 16:07:22 ~9 min windows/status-go 📦zip
✖️ 4c74c55 8 2026-06-22 16:11:36 ~13 min tests-rpc-compat 📄log
✖️ 4c74c55 8 2026-06-22 16:15:15 ~17 min tests-rpc 📄log
✔️ a9e3a83 9 2026-06-22 17:28:53 ~3 min macos/status-go 📦zip
✔️ a9e3a83 9 2026-06-22 17:31:14 ~6 min linux/status-go 📦zip
✔️ a9e3a83 9 2026-06-22 17:34:52 ~9 min windows/status-go 📦zip
✔️ a9e3a83 9 2026-06-22 17:35:35 ~10 min tests 📄log
✖️ a9e3a83 9 2026-06-22 17:36:01 ~11 min tests-rpc-compat 📄log
✖️ a9e3a83 9 2026-06-22 17:41:13 ~16 min tests-rpc 📄log
✔️ 0b820e3 10 2026-06-22 18:07:52 ~3 min macos/status-go 📦zip
✔️ 0b820e3 10 2026-06-22 18:10:34 ~6 min windows/status-go 📦zip
✔️ 0b820e3 10 2026-06-22 18:10:40 ~6 min linux/status-go 📦zip
✔️ 0b820e3 10 2026-06-22 18:14:40 ~10 min tests 📄log
✖️ 0b820e3 10 2026-06-22 18:19:33 ~15 min tests-rpc 📄log
✖️ 0b820e3 10 2026-06-22 18:20:03 ~16 min tests-rpc-compat 📄log
✔️ 20870ba 11 2026-06-25 16:40:31 ~3 min linux/status-go 📦zip
✔️ 20870ba 11 2026-06-25 16:40:59 ~4 min macos/status-go 📦zip
✔️ 20870ba 11 2026-06-25 16:45:13 ~8 min windows/status-go 📦zip
✔️ 20870ba 11 2026-06-25 16:47:20 ~10 min tests 📄log
✖️ 20870ba 11 2026-06-25 16:56:48 ~20 min tests-rpc 📄log
✔️ 20870ba 11 2026-06-25 17:13:54 ~37 min tests-rpc-compat 📄log
Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ cc22be0 12 2026-06-25 17:51:23 ~4 min macos/status-go 📦zip
✔️ cc22be0 12 2026-06-25 17:51:37 ~4 min linux/status-go 📦zip
✔️ cc22be0 12 2026-06-25 17:54:49 ~7 min windows/status-go 📦zip
✔️ cc22be0 12 2026-06-25 18:00:58 ~13 min tests 📄log
✖️ cc22be0 12 2026-06-25 18:05:11 ~18 min tests-rpc 📄log
✔️ cc22be0 12 2026-06-25 18:33:30 ~46 min tests-rpc-compat 📄log
✖️ cc22be0 13 2026-06-26 13:52:38 ~23 min tests-rpc 📄log
✔️ cc22be0 14 2026-06-26 15:36:52 ~14 min tests-rpc 📄log

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a “pinned communities” bootstrap path to the protocol Messenger startup, allowing one or more community description payloads to be bundled into the binary (or overridden from a local directory) and imported into the DB on first run so communities are visible before store-node fetches complete.

Changes:

  • Embed *.rawpayload.hex community description payload(s) into the binary and add a loader for embedded vs directory-based sources.
  • Add an async Messenger startup bootstrap that imports pinned community payloads for new profiles and then triggers non-blocking store-node refreshes.
  • Add tests and documentation describing the bootstrap behavior and source precedence.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
protocol/README.md Documents pinned community bootstrap behavior and source precedence.
protocol/pinnedcommunities/loader.go Implements loading/decoding pinned payloads from embedded FS or a directory.
protocol/pinnedcommunities/loader_test.go Tests directory loading behavior and validates embedded payloads decode as importable community descriptions.
protocol/messenger.go Starts pinned bootstrap asynchronously during Messenger startup.
protocol/messenger_pinned_communities.go Implements bootstrap logic: load payloads, import via community description handler, and trigger store-node refresh.
protocol/messenger_pinned_communities_integration_test.go Integration coverage for import + “first-run only” semantics.
protocol/messenger_communities.go Adds optional env-controlled dumping of community raw payloads to *.rawpayload.hex files.
protocol/communities/persistence.go Adds a DB count query helper for communities table.
protocol/communities/manager.go Exposes Count() and hardens token metadata fetch against nil services/data (plus initializes token supply).
pinned-communities/embedded.go Declares the embedded FS (//go:embed *.rawpayload.hex).
pinned-communities/0x02b5bdaf5a25fcfe2ee14c501fab1836b8de57f61621080c3d52073d16de0d98d6.rawpayload.hex Adds the embedded pinned community payload blob.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread protocol/messenger_pinned_communities.go Outdated
Comment thread protocol/messenger_pinned_communities.go Outdated
Comment thread protocol/messenger.go Outdated
Comment thread protocol/messenger_pinned_communities_test.go
@jrainville

Copy link
Copy Markdown
Member Author

I just realized that TestBootstrapPinnedCommunitiesImportsIntoDB actually does the full import and it takes less than a second. So I think the reason it's so slow is probably just that the DB is locked during the app start. I'll investigate

@jrainville jrainville force-pushed the feat/pin-status-community branch 2 times, most recently from fd69b75 to 3e6ddaf Compare June 17, 2026 19:33
@jrainville

Copy link
Copy Markdown
Member Author

Good news! I found the root cause of the slow saving. Thankfully, it's not a DB freeze. It's because we fetched and saved the token metadata in the same thread in a blocking (doing network calls).
That was both slow and also introduced the risk of failing to save the community if the token fetching failed.

Now, it is done in another thread and is safe.

The pinned community import now takes less than a second and is show as soon as you open the portal! See the updated video in the description

@jrainville jrainville force-pushed the feat/pin-status-community branch 2 times, most recently from 91d1ba5 to 87dd8aa Compare June 19, 2026 19:26
@codecov

codecov Bot commented Jun 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 59.38697% with 106 lines in your changes missing coverage. Please review.
✅ Project coverage is 62.13%. Comparing base (a1f739a) to head (cc22be0).

Files with missing lines Patch % Lines
protocol/messenger_pinned_communities.go 47.36% 55 Missing and 15 partials ⚠️
protocol/messenger_communities.go 36.84% 10 Missing and 2 partials ⚠️
protocol/communities/manager.go 74.35% 7 Missing and 3 partials ⚠️
protocol/pinnedcommunities/loader.go 81.39% 5 Missing and 3 partials ⚠️
protocol/communities/persistence.go 57.14% 2 Missing and 1 partial ⚠️
protocol/messenger.go 57.14% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #7562      +/-   ##
===========================================
- Coverage    62.17%   62.13%   -0.05%     
===========================================
  Files          855      857       +2     
  Lines       119159   119415     +256     
===========================================
+ Hits         74091    74200     +109     
- Misses       37495    37639     +144     
- Partials      7573     7576       +3     
Flag Coverage Δ
functional 41.92% <16.47%> (-0.30%) ⬇️
unit 55.87% <56.70%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
protocol/messenger_config.go 96.53% <100.00%> (+0.08%) ⬆️
services/ext/service.go 30.23% <100.00%> (+1.09%) ⬆️
protocol/communities/persistence.go 72.13% <57.14%> (-0.07%) ⬇️
protocol/messenger.go 62.02% <57.14%> (+0.18%) ⬆️
protocol/pinnedcommunities/loader.go 81.39% <81.39%> (ø)
protocol/communities/manager.go 62.98% <74.35%> (-0.14%) ⬇️
protocol/messenger_communities.go 53.50% <36.84%> (-0.32%) ⬇️
protocol/messenger_pinned_communities.go 47.36% <47.36%> (ø)

... and 39 files with indirect coverage changes

@noeliaSD noeliaSD left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

@jrainville jrainville force-pushed the feat/pin-status-community branch 5 times, most recently from 0b820e3 to 20870ba Compare June 25, 2026 16:36
Fixes status-im/status-app#20954

This commit adds a production-ready pinned community bootstrap flow so the app can show preloaded communities immediately on first launch, even before network fetches complete. Pinned payloads are now bundled into the binary and used by default, with an optional directory override for local development. The bootstrap is guarded to run only for new profiles, preserving existing data for returning users.

During startup, pinned community payloads are imported through the existing community description handling path, then a non-blocking store-node refresh is triggered per imported community so fresher metadata replaces seeded data shortly after launch. The bootstrap runs asynchronously to avoid delaying app start.

The import flow now also publishes imported communities back to the app through the standard messenger response signal path, so UI state can update immediately instead of waiting for a separate fetch cycle. Tests were added and updated to validate embedded payload loading, database import behavior, and first-run-only semantics, and documentation was updated to describe source precedence and runtime behavior.
Part of status-im/status-app#20954

I found that saving a big community, like the Status app, for the first time is very slow, averaging 35 seconds.
Turns out the reason is because of the community tokens. The community description handling called the token data fetching in the same thread and in a blocking way. Meaning that nothing was returned until the tokens were fetched. It also means that if the token fetching failed, the whole community saving and signaling would fail.

I moved the token handling in another thread, so that it doesn't slow the main operation. Then, once the fetching and saving is done, we signal again the new community data
@jrainville jrainville force-pushed the feat/pin-status-community branch from 20870ba to cc22be0 Compare June 25, 2026 17:46
@jrainville jrainville merged commit 2bee8b6 into develop Jun 26, 2026
24 checks passed
@jrainville jrainville deleted the feat/pin-status-community branch June 26, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pin Status Community on Community page at build level so it appears before full network fetch

5 participants