Skip to content

test: revive node+wallet multi-process integration suite - #772

Open
iho wants to merge 4 commits into
mimblewimble:stagingfrom
iho:feat/revive-integration-tests
Open

test: revive node+wallet multi-process integration suite#772
iho wants to merge 4 commits into
mimblewimble:stagingfrom
iho:feat/revive-integration-tests

Conversation

@iho

@iho iho commented Jul 10, 2026

Copy link
Copy Markdown

Summary

  • Revive the long-dead integration crate (commented-out 1.1.0 deps / pre-split APIs).
  • New multi-process tests run a real grin_servers 5.4.1 node with wallet foreign listeners:
    • mine coinbase into a wallet and verify summary via owner API
    • two-wallet slate send/receive + post against the live node
  • Remove obsolete node-only suites (simulnet, stratum, v1 REST API probes). Those now live in mimblewimble/grin#3910 (#2957).
  • Include the crate in the workspace and Linux CI matrix (--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)
  • CI Linux integration job green
  • Existing matrix jobs still green

iho added 2 commits July 11, 2026 00:42
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).
@wiesche89
wiesche89 self-requested a review July 22, 2026 18:26
@wiesche89
wiesche89 changed the base branch from master to staging July 22, 2026 19:04
@wiesche89

wiesche89 commented Jul 22, 2026

Copy link
Copy Markdown

rebase to staging! Fix merge conflicts, please.

Comment thread integration/Cargo.toml Outdated
#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"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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.

Comment thread integration/tests/common/mod.rs Outdated

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")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed.

Helpers updated for the submodule API:

  • Server::new(cfg, None, None, tokio mpsc channel)
  • DefaultLCProvider without lifetime
  • HTTPNodeClient::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).

Comment thread integration/tests/wallet_node.rs Outdated
@@ -0,0 +1,191 @@
// Copyright 2021 The Grin Developers

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed.

Copyright year updated to 2026.

Comment thread integration/tests/wallet_node.rs Outdated
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| {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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.

Comment thread integration/tests/common/mod.rs Outdated
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 || {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed.

start_foreign_listener now:

  • signals readiness over a channel after ApiServer::start succeeds (and TCP-connect checks the port)
  • surfaces startup errors from the listener thread
  • exposes stop() / Drop that send on the API shutdown channel and join the thread

Comment thread integration/README.md Outdated
@@ -0,0 +1,20 @@
# Wallet + node integration tests

Multi-process tests that run a real Grin node (`grin_servers`) together with

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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.

Comment thread integration/README.md Outdated
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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed.

README links the open mimblewimble/grin#3910 PR and notes those node suites are not merged into grin yet.

Comment thread integration/tests/common/mod.rs Outdated

//! Helpers for multi-process node + wallet integration tests.

#![allow(dead_code)]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed.

Removed #![allow(dead_code)] and unused helpers (peer_addr, seeds, owner listener stub). Only helpers used by the tests remain.

Comment thread integration/tests/common/mod.rs Outdated
}

/// 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) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

cargo fmt --all -- --check currently fails in this file and in wallet_node.rs. Could we run cargo fmt before merging?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed.

Ran cargo fmt --all on the branch.

Comment thread .github/workflows/ci.yaml Outdated
- name: Test ${{ matrix.job_args }}
working-directory: ${{ matrix.job_args }}
run: cargo test --release
# Multi-process node+wallet tests need serial execution (ports / RocksDB).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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.
@iho

iho commented Aug 2, 2026

Copy link
Copy Markdown
Author

Thanks @wiesche89 — rebased/merged onto current staging in 7923030 and replied under each inline thread.

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 (--test-threads=1).

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.
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.

2 participants