test: revive node+wallet multi-process integration suite - #772
Conversation
Replace the bitrotted 1.1.0-era integration crate with modern tests that run a real grin_servers node against grin-wallet foreign/owner listeners (mine to wallet, HTTP slate send/receive). Node-only multi-server coverage now lives in mimblewimble/grin#3910. Wire the crate into the workspace and Linux CI (serial execution).
|
rebase to staging! Fix merge conflicts, please. |
| #grin_p2p = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" } | ||
| #grin_servers = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" } | ||
| # Align with workspace grin crates (node multi-server stack). | ||
| grin_core = "5.4.1" |
There was a problem hiding this comment.
The integration crate still pulls the node crates from crates.io, while staging now uses the pinned grin submodule. In a local merge this resolved two different Grin stacks, and the test build then failed against the current APIs. Could we use the same path dependencies as staging here?
There was a problem hiding this comment.
Fixed in 7923030.
integration/Cargo.toml now uses the same path dependencies as staging (../grin/core, keychain, util, api, p2p, servers) instead of crates.io 5.4.1.
|
|
||
| pub fn start_node(cfg: servers::ServerConfig) -> servers::Server { | ||
| // grin_servers 5.4.1: (config, stop_state, api_chan) | ||
| servers::Server::new(cfg, None, leak_api_chan()).expect("node starts") |
There was a problem hiding this comment.
After rebasing, this helper module still does not compile against current staging: Server::new needs another argument, DefaultLCProvider no longer has a lifetime parameter, HTTPNodeClient::new expects a timeout, and foreign_listener requires a concrete TorConfig. Could we update the complete helper against the submodule API and run cargo test afterwards?
There was a problem hiding this comment.
Fixed.
Helpers updated for the submodule API:
Server::new(cfg, None, None, tokio mpsc channel)DefaultLCProviderwithout lifetimeHTTPNodeClient::new(..., timeout)- Wallet config path + global config for listeners
- Foreign HTTP listener built with
ForeignAPIHandlerV2+ApiServer
cargo test -p grin_wallet_integration --test wallet_node -- --test-threads=1 passes (2/2).
| @@ -0,0 +1,191 @@ | |||
| // Copyright 2021 The Grin Developers | |||
There was a problem hiding this comment.
Fixed.
Copyright year updated to 2026.
| api.tx_lock_outputs(m, &slate)?; | ||
|
|
||
| // Receive on B (in-process foreign; same process as HTTP listener but direct call). | ||
| controller::controller::foreign_single_use(wallet_b.clone(), mask_b_clone.clone(), |fapi| { |
There was a problem hiding this comment.
The slate is passed directly to wallet B in-process here instead of being sent through its HTTP listener. I removed wallet B’s listener locally and the test still passed. Could we actually send the slate to rec_addr so the test covers the HTTP path it describes?
There was a problem hiding this comment.
Fixed.
Receive now goes through receive_tx_via_http (JSON-RPC check_version + receive_tx on B’s foreign HTTP listener). In-process foreign_single_use is no longer used for this path.
| pub fn start_foreign_listener(wallet: WalletHandle, mask: Option<grin_util::secp::key::SecretKey>, addr: &str) { | ||
| let keychain_mask = Arc::new(Mutex::new(mask)); | ||
| let listen = addr.to_string(); | ||
| thread::spawn(move || { |
There was a problem hiding this comment.
The listener result is discarded and readiness is only assumed after a fixed sleep. A bind or startup failure therefore appears later as a timeout or may remain unnoticed. Could we report startup readiness through a channel and shut down the thread cleanly at the end of the test?
There was a problem hiding this comment.
Fixed.
start_foreign_listener now:
- signals readiness over a channel after
ApiServer::startsucceeds (and TCP-connect checks the port) - surfaces startup errors from the listener thread
- exposes
stop()/Dropthat send on the API shutdown channel and join the thread
| @@ -0,0 +1,20 @@ | |||
| # Wallet + node integration tests | |||
|
|
|||
| Multi-process tests that run a real Grin node (`grin_servers`) together with | |||
There was a problem hiding this comment.
These tests run as threads inside one process, and the owner HTTP listener is currently not used at all. Could we describe this as live node-and-wallet integration with foreign HTTP, or actually add the missing owner and multi-process coverage?
There was a problem hiding this comment.
Fixed (docs).
README now describes this as live node + wallet integration with foreign HTTP receive, in-process Owner API, and threaded (not multi-process) execution. Owner HTTP / multi-process coverage is called out as not present yet.
| Multi-process tests that run a real Grin node (`grin_servers`) together with | ||
| `grin-wallet` foreign/owner HTTP listeners. | ||
|
|
||
| **Node-only** multi-server suites (seeding, propagation, body sync, stratum) |
There was a problem hiding this comment.
The revived node suites are currently still part of the open mimblewimble/grin #3910 PR and do not live in grin yet. Could we link the open PR and phrase this accordingly until it is merged?
There was a problem hiding this comment.
Fixed.
README links the open mimblewimble/grin#3910 PR and notes those node suites are not merged into grin yet.
|
|
||
| //! Helpers for multi-process node + wallet integration tests. | ||
|
|
||
| #![allow(dead_code)] |
There was a problem hiding this comment.
The blanket allow(dead_code) hides the unused owner listener as well as peer_addr and seeds. Could we remove or actually use these helpers and keep the compiler warning enabled?
There was a problem hiding this comment.
Fixed.
Removed #![allow(dead_code)] and unused helpers (peer_addr, seeds, owner listener stub). Only helpers used by the tests remain.
| } | ||
|
|
||
| /// Start foreign HTTP listener (coinbase / slate receive) on a background thread. | ||
| pub fn start_foreign_listener(wallet: WalletHandle, mask: Option<grin_util::secp::key::SecretKey>, addr: &str) { |
There was a problem hiding this comment.
cargo fmt --all -- --check currently fails in this file and in wallet_node.rs. Could we run cargo fmt before merging?
There was a problem hiding this comment.
Fixed.
Ran cargo fmt --all on the branch.
| - name: Test ${{ matrix.job_args }} | ||
| working-directory: ${{ matrix.job_args }} | ||
| run: cargo test --release | ||
| # Multi-process node+wallet tests need serial execution (ports / RocksDB). |
There was a problem hiding this comment.
Grin uses LMDB here, not RocksDB, and the same wording also appears in the README. Could we simply say “fixed ports and data directories” instead?
Grin++ use RocksDB
There was a problem hiding this comment.
Fixed.
CI comment now says “fixed ports and data directories” (Grin uses LMDB, not RocksDB). README matches.
Sync integration tests with staging (grin submodule path deps, Owner/config APIs) and fix review feedback: real foreign HTTP receive path, listener readiness + clean stop, mature/immature balance assertions, README accuracy, fmt, and CI wording for fixed ports/data dirs.
|
Thanks @wiesche89 — rebased/merged onto current Summary: path deps on the grin submodule, helper API updates, real foreign HTTP receive, listener readiness + clean stop, maturity assertions, README/CI wording, fmt. Integration suite: 2/2 green locally ( |
The early stop-before-maturity race failed on CI because the test miner often produced enough blocks to reach maturity before stop_test_miner took effect. Assert exact spendable and immature amounts from height and coinbase_maturity instead.
Summary
integrationcrate (commented-out 1.1.0 deps / pre-split APIs).grin_servers5.4.1 node with wallet foreign listeners:simulnet,stratum, v1 REST API probes). Those now live in mimblewimble/grin#3910 (#2957).--test-threads=1).In-process mock-node wallet coverage remains under
controller/tests/.Test plan
cd integration && cargo test --release -- --test-threads=1(2 tests pass locally)integrationjob green