Skip to content

Conversation

@no30bit
Copy link
Contributor

@no30bit no30bit commented Nov 25, 2025

Description

Send OnNewDoc event to guests.

Related Issue(s)

Closes #629

Description of Changes

  • Tracking app subscriptions
  • Separate from regular ipfs subscriptions

Breaking Changes

Describe any breaking changes and the impact.

Screenshots

If applicable, add screenshots to help explain your changes.

Related Pull Requests

If applicable, list any related pull requests.

Please confirm the following checks

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream module

@no30bit no30bit added this to Catalyst Nov 25, 2025
@no30bit no30bit moved this from New to 🏗 In progress in Catalyst Nov 25, 2025
cong-or added a commit that referenced this pull request Nov 25, 2025
  Replace async hermes-ipfs library with synchronous WIT bindings (file_add, file_pin, pubsub_publish, pubsub_subscribe). Add actual channel subscription in SyncChannel::new() and
  document complete pub/sub flow with PR #691 infrastructure.

  Changes:
  - Use WIT IPFS functions directly instead of async library
  - Call pubsub_subscribe() to register DocSync subscriptions
  - Document how on_new_doc events are triggered by PR #691
  - Remove conditional compilation and async dependencies
  - Show clear 4-step workflow: add → pin → validate → publish
cong-or added a commit that referenced this pull request Nov 25, 2025
  Add comprehensive comments explaining PR #691 requirement for subscription event routing. Document the complete pub/sub flow, what works now vs what needs PR #691, and how to
  integrate when it merges
cong-or added a commit that referenced this pull request Nov 25, 2025
  Fix compilation error and clarify that publishing to PubSub works now; PR #691 is only needed to route incoming messages to event handlers.
@no30bit no30bit marked this pull request as ready for review November 27, 2025 13:23
cong-or added a commit that referenced this pull request Nov 27, 2025
* feat: implement doc-sync channel::post API for issue #628

- Add channel::post(document_bytes) API as requested
- Integrate hermes-ipfs library for IPFS operations
- Add HTTP endpoints for testing (/api/doc-sync/*)
- Configure HTTP gateway routing
- Implement IPFS add, pin, and PubSub publish workflow

* feat: implement doc-sync channel::post API for issue #628

- Add channel::post(document_bytes) API as requested
- Integrate hermes-ipfs library for IPFS operations
- Add HTTP endpoints for testing (/api/doc-sync/*)
- Configure HTTP gateway routing
- Implement IPFS add, pin, and PubSub publish workflow

* hermes ipfs version

* fix: enable WASM compilation for doc-sync module and add host stubs

  WASM compilation fixes:
  - Made tokio runtime features conditional (rt-multi-thread only for non-WASM)
  - Added separate WASM/native implementations using futures::executor for WASM
  - Conditionally compile Runtime usage and block_on calls

  Host implementation:
  - Replaced panicking todo!() with warning messages and stub return values
  - Added Resource stub creation for SyncChannel::new()
  - Functions now print warnings but don't crash runtime

  This allows the doc-sync module to compile for wasm32-wasip2 targets and
  run without panicking, though full functionality requires proper host
  implementation.

* Remove all cfg attributes and consolidate WASM/non-WASM code paths into single implementations using futures::executor. Simplify HTTP handlers and reduce complexity to clearly
   demonstrate the 4-step workflow.

* refactor(doc-sync): simplify for demo workflow

   Remove conditional compilation, OnceLock pattern, and unnecessary complexity to clearly show the 4-step IPFS PubSub workflow.

* refactor(doc-sync): use WIT bindings directly for demo

  Replace async hermes-ipfs library with direct WIT function calls (file_add, file_pin, pubsub_publish). Remove conditional compilation and async dependencies to simplify the 4-step
  workflow demo.

* refactor(doc-sync): use WIT bindings directly for demo

  Replace async hermes-ipfs library with direct WIT function calls (file_add, file_pin, pubsub_publish). Remove conditional compilation and async dependencies to simplify the 4-step
  workflow demo.

* refactor(doc-sync): integrate with PR #691 subscription flow

  Replace async hermes-ipfs library with synchronous WIT bindings (file_add, file_pin, pubsub_publish, pubsub_subscribe). Add actual channel subscription in SyncChannel::new() and
  document complete pub/sub flow with PR #691 infrastructure.

  Changes:
  - Use WIT IPFS functions directly instead of async library
  - Call pubsub_subscribe() to register DocSync subscriptions
  - Document how on_new_doc events are triggered by PR #691
  - Remove conditional compilation and async dependencies
  - Show clear 4-step workflow: add → pin → validate → publish

* docs(doc-sync): document PR #691 integration requirements

  Add comprehensive comments explaining PR #691 requirement for subscription event routing. Document the complete pub/sub flow, what works now vs what needs PR #691, and how to
  integrate when it merges

* fix(doc-sync): import GuestSyncChannel trait and clarify PR #691 comment

  Fix compilation error and clarify that publishing to PubSub works now; PR #691 is only needed to route incoming messages to event handlers.

* update docs

* refactor(doc-sync): Focus module on publishing workflow only

  Remove subscription logic and simplify documentation. Module now
  demonstrates only the 4-step publishing workflow: file_add, file_pin,
  pre-publish validation, and pubsub_publish.

* fmt

* refactor(doc-sync): Move post logic to host

  Execute the 4-step publishing workflow (file_add, file_pin, pre-publish,
  pubsub_publish) on the host side instead of in the WASM module. Reduces
  boundary crossings from 6 to 2 for better performance.

* fmt

* fmt

* fix(doc-sync): Fix compilation errors

  - Fix SyncChannel resource import and usage
  - Update channel::post() to call host implementation correctly

* refactor(doc-sync): Replace eprintln with tracing

  Use tracing macros (info/warn/error) instead of eprintln for logging
  in doc-sync host implementation.

* refactor(doc-sync): Replace eprintln with tracing

  Use tracing macros (info/warn/error) instead of eprintln for logging
  in doc-sync host implementation.

* fmt

* refactor(doc-sync): Extract constants and improve error logging

  - Add DOC_SYNC_TOPIC and DOC_SYNC_CHANNEL constants
  - Add error logging to id_for() method

* refactor(doc-sync): Improve error logging and remove redundant conversions

  - Log actual error details instead of discarding with
  - Remove redundant .to_string() on CID response
  - Add error logging for failed post operations

* fmt
rafal-ch added a commit that referenced this pull request Dec 2, 2025
* feat: implement doc-sync channel::post API for issue #628

- Add channel::post(document_bytes) API as requested
- Integrate hermes-ipfs library for IPFS operations
- Add HTTP endpoints for testing (/api/doc-sync/*)
- Configure HTTP gateway routing
- Implement IPFS add, pin, and PubSub publish workflow

* feat: implement doc-sync channel::post API for issue #628

- Add channel::post(document_bytes) API as requested
- Integrate hermes-ipfs library for IPFS operations
- Add HTTP endpoints for testing (/api/doc-sync/*)
- Configure HTTP gateway routing
- Implement IPFS add, pin, and PubSub publish workflow

* hermes ipfs version

* fix: enable WASM compilation for doc-sync module and add host stubs

  WASM compilation fixes:
  - Made tokio runtime features conditional (rt-multi-thread only for non-WASM)
  - Added separate WASM/native implementations using futures::executor for WASM
  - Conditionally compile Runtime usage and block_on calls

  Host implementation:
  - Replaced panicking todo!() with warning messages and stub return values
  - Added Resource stub creation for SyncChannel::new()
  - Functions now print warnings but don't crash runtime

  This allows the doc-sync module to compile for wasm32-wasip2 targets and
  run without panicking, though full functionality requires proper host
  implementation.

* Remove all cfg attributes and consolidate WASM/non-WASM code paths into single implementations using futures::executor. Simplify HTTP handlers and reduce complexity to clearly
   demonstrate the 4-step workflow.

* refactor(doc-sync): simplify for demo workflow

   Remove conditional compilation, OnceLock pattern, and unnecessary complexity to clearly show the 4-step IPFS PubSub workflow.

* refactor(doc-sync): use WIT bindings directly for demo

  Replace async hermes-ipfs library with direct WIT function calls (file_add, file_pin, pubsub_publish). Remove conditional compilation and async dependencies to simplify the 4-step
  workflow demo.

* refactor(doc-sync): use WIT bindings directly for demo

  Replace async hermes-ipfs library with direct WIT function calls (file_add, file_pin, pubsub_publish). Remove conditional compilation and async dependencies to simplify the 4-step
  workflow demo.

* refactor(doc-sync): integrate with PR #691 subscription flow

  Replace async hermes-ipfs library with synchronous WIT bindings (file_add, file_pin, pubsub_publish, pubsub_subscribe). Add actual channel subscription in SyncChannel::new() and
  document complete pub/sub flow with PR #691 infrastructure.

  Changes:
  - Use WIT IPFS functions directly instead of async library
  - Call pubsub_subscribe() to register DocSync subscriptions
  - Document how on_new_doc events are triggered by PR #691
  - Remove conditional compilation and async dependencies
  - Show clear 4-step workflow: add → pin → validate → publish

* docs(doc-sync): document PR #691 integration requirements

  Add comprehensive comments explaining PR #691 requirement for subscription event routing. Document the complete pub/sub flow, what works now vs what needs PR #691, and how to
  integrate when it merges

* fix(doc-sync): import GuestSyncChannel trait and clarify PR #691 comment

  Fix compilation error and clarify that publishing to PubSub works now; PR #691 is only needed to route incoming messages to event handlers.

* update docs

* refactor(doc-sync): Focus module on publishing workflow only

  Remove subscription logic and simplify documentation. Module now
  demonstrates only the 4-step publishing workflow: file_add, file_pin,
  pre-publish validation, and pubsub_publish.

* fmt

* refactor(doc-sync): Move post logic to host

  Execute the 4-step publishing workflow (file_add, file_pin, pre-publish,
  pubsub_publish) on the host side instead of in the WASM module. Reduces
  boundary crossings from 6 to 2 for better performance.

* fmt

* fmt

* fix(doc-sync): Fix compilation errors

  - Fix SyncChannel resource import and usage
  - Update channel::post() to call host implementation correctly

* refactor(doc-sync): Replace eprintln with tracing

  Use tracing macros (info/warn/error) instead of eprintln for logging
  in doc-sync host implementation.

* refactor(doc-sync): Replace eprintln with tracing

  Use tracing macros (info/warn/error) instead of eprintln for logging
  in doc-sync host implementation.

* fmt

* refactor(doc-sync): Extract constants and improve error logging

  - Add DOC_SYNC_TOPIC and DOC_SYNC_CHANNEL constants
  - Add error logging to id_for() method

* refactor(doc-sync): Improve error logging and remove redundant conversions

  - Log actual error details instead of discarding with
  - Remove redundant .to_string() on CID response
  - Add error logging for failed post operations

* fmt

* fmt

* refactor(doc-sync): Replace stub implementations with todo!()

  Replace placeholder implementations with explicit todo!() markers:
  - id_for: Remove incorrect file_add call with side effects
  - sync-channel::new: Remove placeholder resource ID (42)
  - sync-channel::close: Remove stub return value

  These are out of scope for post() implementation and should panic if
  called.

* Update hermes/bin/src/ipfs/task.rs

Co-authored-by: Rafał Chabowski <[email protected]>

* docs(doc-sync): Move crate docs to README and remove duplication

  Move module documentation from lib.rs to a crate-level README.md for better visibility and remove duplicated content between crate-level and channel module docs.

* docs(doc-sync): Move crate docs to README and remove duplication

  Move module documentation from lib.rs to a crate-level README.md for better visibility and remove duplicated content between crate-level and channel module docs.

* fix(doc-sync): Fix markdown linting errors in README

  Split long sentences to one per line and ensure lines stay under 132 character limit.

* fix(doc-sync): Replace todo!() with placeholder implementations

  Replace 5 todo!() macros in doc_sync host with minimal placeholder
  implementations to pass clippy lint checks. Functions now return
  empty/default values instead of panicking.

* fix(doc-sync): Resolve all clippy pedantic lints

  Fixes documentation formatting, format string inlining, unnecessary value passing, wildcard imports, and missing error documentation to satisfy clippy::pedantic requirements

* Log pin result

* IPFS file add operation now also returns CID

* Fixes after the merge

* Remove the pin step

* Remove the pin step

* Cleanup

* Cleanup

* DHT provide on the host side

* Wire the `IpfsCommand::DhtProvide` command

* Add `is_pre_publish_completed()`

* Implement basic timeout

* Implement DHT get providers

* Use proper peer ID

* Update test component

* Temp switch to `main` branch in libs

* Cleanup

* Split `fn post()` into auxiliary functions

* Update `hermes-ipfs`

* Update comment

* Fix typo

* Fix typo

* Revert unnecessary comment change

* Use correct error in `dht_provide()`

* Use proper error in `IpfsCommand::DhtGetProviders()`

---------

Co-authored-by: cong-or <[email protected]>
@no30bit no30bit requested a review from aido-mth December 15, 2025 14:05
@no30bit no30bit moved this from 🏗 In progress to 👀 In review in Catalyst Dec 16, 2025
@github-actions
Copy link

📚 Docs Preview

The docs for this PR can be previewed at the following URL:

https://docs.dev.projectcatalyst.io/hermes/feat/629/send-on-new-doc

cong-or and others added 6 commits December 17, 2025 12:13
* feat: Add multi-node P2P testing infrastructure (#704)

  Docker-based setup for testing IPFS PubSub/P2P across multiple Hermes nodes.

  ## Changes
  - HTTP port configurable via HERMES_HTTP_PORT (default: 5000)
  - Created p2p-testing/ with 3-node Docker setup on isolated network
  - Leverages justfile recipes for builds

* feat(p2p-testing): Add cross-platform build checks and improve error handling

  Enhances the P2P testing infrastructure to ensure cross-platform compatibility
  and provide better error handling for common Docker issues.

  Changes:
  - Add error handling for Docker network and container conflicts in start-nodes.sh
  - Emphasize Earthly (containerized builds) for GLIBC compatibility across different host OS
  - Add comprehensive documentation about cross-platform build requirements
  - Update Dockerfile and docker-compose.yml with clear build instructions
  - Add troubleshooting section for GLIBC errors in README

  The scripts now detect and provide helpful error messages for:
  - Network subnet overlaps with existing Docker networks
  - Container name conflicts from previous runs
  - Guidance to use Earthly builds instead of local cargo builds

  This ensures the P2P testing environment works reliably across different
  development environments (Fedora, Ubuntu, macOS, etc.) by building binaries
  in a controlled container environment that matches the Docker runtime GLIBC version.

* feat(hermes): Enable P2P transports for IPFS connectivity

  Enable TCP, QUIC, and DNS transports when initializing IPFS node.
  Update hermes-ipfs dependency to use transport enable methods branch.

  Changes:
  - Add enable_tcp(), enable_quic(), enable_dns() calls in ipfs/mod.rs
  - Update Cargo.toml to use feat/hermes-ipfs-transport-enable-methods branch

  Fixes "Multiaddr is not supported" errors preventing P2P connections.

  Related to: #704

* fix(ipfs): Remove process::exit that caused premature shutdown

  The IPFS initialization thread was calling std::process::exit(0) when the
  ipfs_command_handler task completed, causing the entire hermes process to
  exit cleanly after 1-2 minutes of runtime.

  Root cause:
  - IPFS node spawned a background thread (ipfs/mod.rs:101)
  - Thread ran ipfs_command_handler in a tokio runtime
  - When handler task finished, tokio::join! completed
  - Thread then called std::process::exit(0), killing entire process

  This resulted in:
  - Nodes exiting with status 0 (clean exit, no error logs)
  - P2P connections working initially but then everything stopped
  - Consistent timing (~1-2 minutes until exit)

  Fix:
  - Removed std::process::exit(0) call
  - Added proper error logging for IPFS thread failures
  - Thread now returns naturally instead of killing the process

  Impact:
  - Nodes now run indefinitely as intended
  - Multi-node P2P testing infrastructure is stable
  - PubSub discovery and connectivity working correctly

* feat(p2p): Add custom bootstrap peers and initialization script

  Enable custom P2P bootstrap configuration for multi-node testing:
  - Add IPFS_BOOTSTRAP_PEERS environment variable support for custom peer lists
  - Update bootstrap() to accept optional custom peers parameter
  - Add initialize-p2p.sh script to extract peer IDs and generate bootstrap config
  - Update hermes-ipfs dependency from 0.0.6 to 0.0.8

  This allows nodes in Docker environments to bootstrap to each other
  instead of public IPFS nodes, enabling isolated P2P testing.

* feat(p2p): Add persistent peer identity, bootstrap retry, and testing
   justfile

   Implements core P2P infrastructure improvements:

   - Persistent IPFS keypairs (~/.hermes/ipfs/keypair) for stable peer IDs
   - Bootstrap retry logic (10s interval, 10 max) for automatic reconnection
   - Port 4001 listening configuration for P2P connections
   - Comprehensive justfile with 17 commands (build, test, monitor)
   - PubSub testing command verifying Gossipsub v1.2 and peer connections
   - Updated docker-compose.yml with persistent peer IDs

   Dependencies:
   - hermes-ipfs updated to feat/hermes-ipfs-persistent-keypair branch

   Verified on 3-node Docker setup with full mesh connectivity.

* refactor(p2p): Make justfile self-documenting and minimize README

  - Add comprehensive documentation to justfile header and commands
  - Reduce README from 327 to 56 lines (points to justfile)
  - Remove legacy shell scripts directory (consolidated into justfile)
  - Remove obsolete files (.env.bootstrap, docker-compose.yml.backup)

  All documentation now in justfile with organized sections, inline
  comments, and detailed help command. README provides quick start only

* fix(p2p): Enable PubSub mesh formation and DHT for 6-node testing

  - Auto-subscribe all nodes to documents.new topic on startup to form
    Gossipsub mesh (requires mesh_n=6 peers for optimal operation)
  - Add nodes 4-6 to reach minimum Gossipsub mesh size
  - Fix DHT provider check to accept local node in isolated networks
  - Extend DHT provider timeout and add detailed logging
  - Document why 6 nodes are required in README and justfile

  This allows PubSub publish to succeed by ensuring the topic mesh is
  formed before any POST requests, and relaxes DHT provider requirements
  for small test networks where nodes don't replicate content proactively.

* fix(p2p): Implement on-topic handler to enable PubSub message reception

  PubSub was publishing successfully but messages weren't being received
  because the doc-sync module was missing the hermes:ipfs/event.on-topic
  handler. The system dispatches OnTopicEvent but the module only exported
  hermes:doc-sync/event, not hermes:ipfs/event.

  Changes:
  - Add hermes:ipfs/event export to doc-sync module world definition
  - Implement on-topic event handler with detailed logging
  - Add comprehensive logging throughout PubSub publish path
  - Enhance error reporting in doc_sync host publish function
  - Update p2p-testing justfile with parallel module packaging
  - Add test-pubsub-propagation recipe for end-to-end testing
  - Update docker-compose bootstrap peers with current peer IDs

  The on-topic handler now logs all received PubSub messages with topic,
  size, and message preview, making it easy to verify propagation across
  the 6-node test mesh.

  Root cause: Mismatch between dispatched event (OnTopicEvent calling
  hermes:ipfs/event.on-topic) and module exports (only hermes:doc-sync/event).
  Messages were successfully published and routed by Gossipsub but dropped
  at the module boundary due to missing handler.

* fix(p2p): Implement on-topic handler and bootstrap discovery for PubSub

  PubSub messages were published successfully but never received because
  the doc-sync module was missing the hermes:ipfs/event.on-topic handler.
  The runtime dispatches PubSub messages as OnTopicEvent, but the module
  only exported hermes:doc-sync/event.

  Additionally, docker-compose.yml has hardcoded bootstrap peer IDs that
  become stale when volumes are deleted, causing [wrong peer id] errors.

  Changes:
  - Add hermes:ipfs/event export and on-topic handler to doc-sync module
  - Add detailed PubSub logging throughout publish/receive path
  - Add init-bootstrap command to sync docker-compose.yml after volume deletion
  - Document PR#694 persistent keypairs (already working, just needed docs)
  - Clarify when init-bootstrap is needed (after clean, not after restart)

* fix(p2p): Fix bootstrap discovery and enable end-to-end PubSub testing in CI

  Three critical fixes to P2P testing infrastructure:

  1. init-bootstrap: Detect both Generated and Loaded keypair messages
     - Previously only matched Generated new keypair with Peer ID:
     - Now handles Loaded keypair with Peer ID: for persistent volumes
     - Fixes bootstrap discovery after first run when keypairs exist

  2. test-pubsub-propagation: Fix bash arithmetic causing premature exit
     - Changed ((RECEIVED_COUNT++)) to RECEIVED_COUNT=1
     - With set -euo pipefail, post-increment returned 0 causing exit code 1
     - Test now correctly reports all 5 nodes receiving messages

  3. CI workflow: Add bootstrap init and message propagation test
     - start-ci now runs init-bootstrap to sync peer IDs
     - test-ci now includes test-pubsub-propagation for end-to-end verification
     - Ensures CI validates actual PubSub message delivery, not just infrastructure

  These changes enable reliable CI testing of P2P features with proper
  bootstrap configuration and functional validation of message propagation
  across all 6 nodes.

* fix(p2p): Ensure start-ci always begins from clean state

  Add automatic cleanup to start-ci command to guarantee reproducible
  CI environment. The command now checks for running nodes and executes
  docker compose down -v before building and starting.

  This ensures CI runs are always deterministic by:
  - Removing stale containers and volumes
  - Forcing fresh peer identity generation
  - Preventing state pollution between runs

  Simplifies CI workflow to single command: just start-ci && just test-ci

* feat(p2p-testing): enhance UX with visualization and clearer documentation

  - Add visual HTTP POST flow diagram explaining why Node 1 is publisher
  - Enhance test-pubsub-propagation with 4 insight sections:
    * Propagation timeline with receive timestamps
    * Network statistics (message size, success rate, latency)
    * Live log preview showing PubSub activity
    * Peer connection matrix showing full mesh
  - Add educational explanations of Gossipsub, PubSub topics, and CIDs
  - Add workflow diagram to README showing daily command flow
  - Clarify interactive mode (start) vs CI mode (start-ci) throughout docs
  - Emphasize peer ID lifecycle: preserved with 'stop', regenerated after 'clean'
  - Update help command with important notes section

  Makes P2P testing infrastructure more accessible and educational for new users.

* refactor(p2p): Add helper functions and improve test maintainability

  - Add 7 reusable helper functions to eliminate code duplication
  - Refactor test-pubsub-core using helpers (65 → 35 lines)
  - Standardize color code format across 8 recipes
  - Add curl command explanation to PubSub test visualization
  - Fix documentation references for test-pubsub-propagation

  No functional changes. Improves maintainability and readability.

* refactor(p2p): Simplify testing infrastructure by removing redundant commands

   Remove dashboard and health-check commands (~195 lines) since test-pubsub-propagation
   already validates all necessary functionality (nodes running status, mesh connectivity
   via message propagation, gossipsub activity via successful delivery, end-to-end P2P).

   Fix HTTP endpoint health check to include required Host header for Hermes gateway.

* refactor(p2p): Make test-pubsub test actual propagation and add millisecond timing

  Update test-pubsub to publish messages and verify reception on all nodes (minimal output for CI), matching test-pubsub-propagation functionality. Remove redundant test-pubsub-core
  command.

  Improve timing precision from seconds to milliseconds using date +%s%3N, showing actual sub-second propagation delays (0.234s instead of 0s) in visualization and final status.

* docs(p2p): improve documentation accuracy and usability

  Restructure README with TL;DR and fast restart workflows. Fix outdated
  command references (dashboard, test-pubsub-core) and clarify prerequisites
  (Rust toolchain, not Earthly). Remove duplicate entries and confusing
  peer ID examples. Add TODOs for GitHub Actions integration.

  Next task: integrate CI workflow into GitHub Actions runners for automated PR testing.

* docs(p2p): improve docs clarity and add cross-platform build auto-detection

  - Restructure README with TL;DR for minimal cognitive load
  - Add comprehensive comments to docker-compose.yml and Dockerfile
  - Auto-detect platform in build commands (Linux uses cargo, Mac/Windows uses Earthly)
  - Fix outdated references and broken commands
  - Add fast restart workflow documentation
  - Add GitHub Actions integration TODOs

* docs(p2p-testing): enhance clarity and add cross-platform support

  - Add TL;DR quickstart and fast restart workflows
  - Auto-detect platform for builds (Linux cargo, Mac/Windows Earthly)
  - Fix non-existent command references and outdated line numbers
  - Add comprehensive inline comments to docker-compose
  - Expand bootstrap peer discovery docs for production deployment

* chore: update Cargo.lock after merging main

* chore: add http-proxy module manifest and version files

* refactor: eliminate hardcoded values and code duplication

  - Extract MESSAGE_PREVIEW_MAX_LEN constant and create format_message_preview() helper
  - Make IPFS listen port configurable via IPFS_LISTEN_PORT env var (default: 4001)
  - Make retry settings configurable via IPFS_RETRY_INTERVAL_SECS and IPFS_MAX_RETRIES
  - Document exponential backoff strategy for DHT provider queries

  Improves maintainability and configurability without changing behavior.

* refactor(ipfs): extract helper functions and eliminate hardcoded values

  - Add env_var_or() helper to eliminate duplicate env var parsing
  - Extract configure_listening_address() and connect_to_bootstrap_peers() from init()
  - Extract constants: IPFS_DATA_DIR, KEYPAIR_FILENAME, DEFAULT_APP_NAME, DEFAULT_MESH_TOPIC
  - Simplify retry_bootstrap_connections() with early returns and cleaner logic

* docs(ipfs): add conceptual comments for P2P architecture and PubSub constraints

  - Explain what bootstrap peers are and their role in network formation
  - Document retry strategy for bootstrap connections
  - Add critical warning: public IPFS nodes cannot be used for Hermes PubSub
  - Explain why DHT server mode is required for Gossipsub mesh formation
  - Document auto-subscription strategy to avoid cold start problem

  Emphasizes the key constraint that Gossipsub requires custom Hermes bootstrap
  peers since public IPFS nodes don't subscribe to application-specific topics.

* docs(ipfs): add conceptual comments for P2P architecture and PubSub constraints

  - Explain what bootstrap peers are and their role in network formation
  - Document retry strategy for bootstrap connections
  - Add critical warning: public IPFS nodes cannot be used for Hermes PubSub
  - Explain why DHT server mode is required for Gossipsub mesh formation
  - Document auto-subscription strategy to avoid cold start problem

  Emphasizes the key constraint that Gossipsub requires custom Hermes bootstrap
  peers since public IPFS nodes don't subscribe to application-specific topics.

* docs(p2p-testing): add custom test examples and fix ANSI color output

  - Add Writing Custom Tests section with examples (connectivity, resilience, throughput)
  - Include template and best practices for extending justfile tests
  - Fix ANSI escape codes not rendering (add -e flag to echo commands)
  - Note: proper API testing framework planned when endpoints finalized

* docs: improve clarity of P2P networking comments

  - Explain mesh_n parameter and its effect on Gossipsub operations
  - Add TL;DR sections to bootstrap discovery and PubSub warnings
  - Clarify cross-platform builds (cargo vs Earthly) and GLIBC compatibility
  - Add DNS analogy for bootstrap peers concept
  - List explicit 5-step post document workflow
  - Explain logging levels (debug = P2P diagnostics, info = app events)

* docs: improve clarity of P2P networking comments

  - Explain mesh_n parameter and its effect on Gossipsub operations
  - Add TL;DR sections to bootstrap discovery and PubSub warnings
  - Clarify cross-platform builds (cargo vs Earthly) and GLIBC compatibility
  - Add DNS analogy for bootstrap peers concept
  - List explicit 5-step post document workflow
  - Explain logging levels (debug = P2P diagnostics, info = app events)

* Fix DHT provider wait log (host.rs:361–372):

- Replace confusing need 2+ / 1+ messages with clear explanations
- Old: got 1 provider(s), need 2+
- New: found 1 provider(s), waiting for ourselves to appear in DHT query results
- The 2+ / 1+ thresholds did not match actual success conditions

* Simplify TROUBLESHOOTING.md Complete Reset:
  - Remove redundant build-all/build-images steps (quickstart handles this)
  - Clarify difference between nuclear option (prunes all Docker resources)
    vs just clean (only removes p2p-testing volumes)

* docs: improve clarity and fix clippy warnings

  - Explain mesh_n, bootstrap peers (DNS analogy), and 5-step post workflow
  - Fix confusing DHT log: need 2+ waiting for ourselves to appear
  - Add backticks around PubSub and function names (clippy doc-markdown)
  - Simplify TROUBLESHOOTING reset (quickstart handles rebuilds)
  - Clarify quickstart uses existing binaries (run just build-all after code changes)

* fix: clarify prerequisite validation error messaging

  Replace contradictory per-artifact suggestions (just build vs just
  build-all) with single consolidated action at end. Now clearly directs
  users to run just build-all when any artifacts are missing, matching
  the quickstart workflow.

* fix: clarify prerequisite validation error messaging

  Replace contradictory per-artifact suggestions (just build vs just
  build-all) with single consolidated action at end. Now clearly directs
  users to run just build-all when any artifacts are missing, matching
  the quickstart workflow.

* fix: allow quickstart to proceed when build artifacts are missing

  Changed validate-prereqs to treat missing build artifacts as warnings
  instead of errors. Previously, quickstart would fail validation and exit
  before reaching Step 2 where it automatically builds missing artifacts.
  Now validation passes and quickstart proceeds to build them as intended.

  Also updated help text to clarify that quickstart handles building
  automatically.

* docs: fix markdown linting and spell check errors

  Fix all markdown linting errors in p2p-testing docs:
  - Convert list dashes to asterisks
  - Add blank lines around code blocks and lists
  - Split long lines and multi-sentence lines
  - Convert bold emphasis to proper headings

  Add technical terms to cspell dictionary: keypair variants,
  multiaddr, prereqs, tuln, usermod, QUIC, protobuf, ipam, distro

* fmt

* ci

* fix: add backticks around PubSub in doc comments

* fix: handle UTF-8 boundaries in message preview truncation

* fix: resolve IPFS initialization race condition in integration tests

  This commit fixes two issues causing integration test failures on the
  multi-node P2P testing branch:

  1. Race condition in IPFS initialization:
     - Added oneshot channel synchronization to ensure the IPFS command
       handler is fully ready before bootstrap() returns
     - Prevents auto-subscribe from failing when called immediately after
       init, as the command handler may not be running yet
     - The auto-subscribe is critical for P2P mesh formation

  2. IPFS bootstrap timeouts in tests:
     - Set IPFS_BOOTSTRAP_PEERS= environment variable in integration
       tests to disable public IPFS bootstrap
     - Integration tests don't require real P2P connectivity
     - Prevents 5+ minute timeouts trying to connect to public nodes

* fix: correct is_pre_publish_completed to require other peers

  The function was incorrectly returning true when only the publishing
  node appeared in DHT results. This violated the documented contract
  to wait until the given CID is provided by at least one other peer.

  Now properly checks for at least one provider other than ourselves,
  ensuring DHT propagation to other peers is actually verified before
  considering pre-publish complete.

  Fixes test: pre_publish_completed::_our_expects_false
Copy link
Contributor

@rafal-ch rafal-ch left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@aido-mth aido-mth enabled auto-merge (squash) December 17, 2025 12:06
@aido-mth aido-mth merged commit 944360f into main Dec 17, 2025
56 checks passed
@aido-mth aido-mth deleted the feat/629/send-on-new-doc branch December 17, 2025 13:21
@github-project-automation github-project-automation bot moved this from 👀 In review to ✅ Done in Catalyst Dec 17, 2025
cong-or added a commit that referenced this pull request Dec 21, 2025
  WHAT THIS FIXES:
  - CID format: Use dag-cbor codec (0x51) instead of dag-pb (0x70) for protocol compliance
  - Message encoding: Publish CBOR-encoded payload::New with CID lists instead of raw document bytes
  - Subscription conflict: Remove auto-subscription that prevented doc-sync module from subscribing

  CHANGES:
  - hermes/bin/src/runtime_extensions/hermes/doc_sync/host.rs:
    * Import minicbor crate directly (not via cardano_chain_follower)
    * Compute both dag-pb CID (storage) and dag-cbor CID (protocol) in add_file()
    * Construct proper payload::New structure in publish()
    * Encode to CBOR before publishing to PubSub

  - hermes/bin/src/ipfs/mod.rs:
    * Remove auto-subscription to documents.new during bootstrap
    * Prevents subscription kind conflicts with doc-sync module

  - hermes/bin/src/ipfs/task.rs:
    * Add extensive documentation of blocking operations issue
    * Document root cause and recommended async solution

  REMAINING ISSUE:
  P2P propagation still fails due to blocking operations in async context.
  The doc_sync_topic_message_handler (added in 944360f) calls file_pin()
  and file_get() which use blocking_send()/blocking_recv(). This causes
  deadlock when called from async PubSub handler.

  NEXT STEPS:
  Convert file_pin() and file_get() to async versions. See detailed
  implementation guide in task.rs comments (lines 354-374).

  TEST:
  cd p2p-testing && just test-pubsub-propagation
  Currently FAILS with No Propagation due to blocking operations issue.
  Will PASS once async conversion is complete.

  Related: #691 (introduced blocking operations bug)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

🛠️ [TASK]: Allow Hermes to process docs received via PubSub channel

6 participants