Skip to content

Switch to private testnet and upgrade - #105

Merged
napoly merged 1 commit into
btcpay-monero:masterfrom
napoly:switch-to-private-testnet
Jul 25, 2026
Merged

Switch to private testnet and upgrade#105
napoly merged 1 commit into
btcpay-monero:masterfrom
napoly:switch-to-private-testnet

Conversation

@napoly

@napoly napoly commented Jun 6, 2026

Copy link
Copy Markdown
Member

https://moneroexamples.github.io/private-testnet/

related to: btcpay-monero/monero-csharp#80

Summary by CodeRabbit

  • Tests
    • Updated Monero integration test wallet data and RPC inputs to use new hardcoded key material.
    • Enhanced Monero integration test infrastructure to support a two-daemon topology rather than a single daemon.
    • Adjusted wallet-to-daemon connectivity and test environment settings to match the new multi-node setup.
    • Refreshed test service configuration, including an updated Postgres image, and split Monero node data volumes for improved reliability.

@codacy-production

codacy-production Bot commented Jun 6, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

🟢 Coverage ∅ diff coverage · -0.24% coverage variation

Metric Results
Coverage variation -0.24% coverage variation (-1.00%)
Diff coverage diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (8e77d6c) 828 501 60.51%
Head commit (b069001) 828 (+0) 499 (-2) 60.27% (-0.24%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#105) 0 0 ∅ (not applicable)

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@nahuhh

nahuhh commented Jun 6, 2026

Copy link
Copy Markdown

Might make more sense to use regtest

edit: i just noticed that it was using regtest before.
i dont think it makes any sense to switch to testnet. iirc, youd also have to change the hard fork table, otherwise your private testnet will be using old fork rules. regtest uses the latest.

so, nack changing to a private testnet. All of this can be done more cleanly using a private regtest network.

@napoly
napoly requested a review from deverickapollo June 6, 2026 12:34
@napoly
napoly force-pushed the switch-to-private-testnet branch from 070a249 to cab1802 Compare June 8, 2026 09:07
Comment on lines -246 to +247
"43Pnj6ZKGFTJhaLhiecSFfLfr64KPJZw7MyGH73T6PTDekBBvsTAaWEUSM4bmJqDuYLizhA13jQkMRPpz9VXBCBqQQb6y5L",
viewkey = "1bfa03b0c78aa6bc8292cf160ec9875657d61e889c41d0ebe5c54fd3a2c4b40e",
"9yEzCbcYdg6MqZ5AkEh8V3YCriyN1tvmtWEHdBEUHkF6D6kN1MMD2Kd2QVWoTY67aNHNYKMUP3xfteLS2QNavJxpJdx6mWj",
viewkey = "1f4668e8c1979b4c7dae13dc149fd95cd7ff2883becffe160c21f9e02c821c08",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why not use regtest and leave these values unchanged?

Comment on lines -44 to +45
"43Pnj6ZKGFTJhaLhiecSFfLfr64KPJZw7MyGH73T6PTDekBBvsTAaWEUSM4bmJqDuYLizhA13jQkMRPpz9VXBCBqQQb6y5L");
"9yEzCbcYdg6MqZ5AkEh8V3YCriyN1tvmtWEHdBEUHkF6D6kN1MMD2Kd2QVWoTY67aNHNYKMUP3xfteLS2QNavJxpJdx6mWj");
await s.Page.Locator("input#PrivateViewKey")
.FillAsync("1bfa03b0c78aa6bc8292cf160ec9875657d61e889c41d0ebe5c54fd3a2c4b40e");
.FillAsync("1f4668e8c1979b4c7dae13dc149fd95cd7ff2883becffe160c21f9e02c821c08");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same

Comment on lines -122 to +124
.FillAsync("1bfa03b0c78aa6bc8292cf160ec9875657d61e889c41d0ebe5c54fd3a2c4b40e");
.FillAsync("1f4668e8c1979b4c7dae13dc149fd95cd7ff2883becffe160c21f9e02c821c08");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same

Comment on lines +141 to +147
PrimaryAddress = "43Pnj6ZKGFTJhaLhiecSFfLfr64KPJZw7MyGH73T6PTDekBBvsTAaWEUSM4bmJqDuYLizhA13jQkMRPpz9VXBCBqQQb6y5L",
PrivateViewKey = "1bfa03b0c78aa6bc8292cf160ec9875657d61e889c41d0ebe5c54fd3a2c4b40e",
WalletFileName = "wallet",
Password = ""
});
await moneroRpcProvider.WalletRpcClients["XMR"]
.SendCommandAsync<GenerateFromKeysRequest, GenerateFromKeysResponse>("generate_from_keys",
new GenerateFromKeysRequest
{
PrimaryAddress =
"9yEzCbcYdg6MqZ5AkEh8V3YCriyN1tvmtWEHdBEUHkF6D6kN1MMD2Kd2QVWoTY67aNHNYKMUP3xfteLS2QNavJxpJdx6mWj",
PrivateViewKey = "1f4668e8c1979b4c7dae13dc149fd95cd7ff2883becffe160c21f9e02c821c08",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same

Comment on lines -152 to +159
.FillAsync("43Pnj6ZKGFTJhaLhiecSFfLfr64KPJZw7MyGH73T6PTDekBBvsTAaWEUSM4bmJqDuYLizhA13jQkMRPpz9VXBCBqQQb6y5L");
.FillAsync("9yEzCbcYdg6MqZ5AkEh8V3YCriyN1tvmtWEHdBEUHkF6D6kN1MMD2Kd2QVWoTY67aNHNYKMUP3xfteLS2QNavJxpJdx6mWj");
await s.Page.Locator("input#PrivateViewKey")
.FillAsync("1bfa03b0c78aa6bc8292cf160ec9875657d61e889c41d0ebe5c54fd3a2c4b40e");
.FillAsync("1f4668e8c1979b4c7dae13dc149fd95cd7ff2883becffe160c21f9e02c821c08");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same

container_name: node_1
command: [
"monerod",
"--fixed-difficulty=150",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I presume this is changed from 1 as to limit the block rate?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this a battle tested value from haveno-ts https://github.com/haveno-dex/haveno-ts/blob/master/docker/docker-compose.yml#L39 to mine blocks efficiently / in time

"--confirm-external-bind",
"--add-exclusive-node=node_2:28080",
"--block-notify=/bin/sh ./scripts/notifier.sh -k -X GET https://host.docker.internal:14142/monerolikedaemoncallback/block?cryptoCode=xmr&hash=%s",
"--testnet",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
"--testnet",
"--regtest",

"--add-exclusive-node=node_2:28080",
"--block-notify=/bin/sh ./scripts/notifier.sh -k -X GET https://host.docker.internal:14142/monerolikedaemoncallback/block?cryptoCode=xmr&hash=%s",
"--testnet",
"--no-igd",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
"--no-igd",

removed upstream in v0.18.5.0

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

command: [
"monero-wallet-rpc",
"--log-level=2",
"--allow-mismatched-daemon-version",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is only needed if using --regtest

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

removed

@napoly

napoly commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

All of this can be done more cleanly using a private regtest network.

@nahuhh thanks for looking into this direction, you aren't the first one to question

The main reason for testnet over regtest is realism.. real PoW, nothing mocked away. It's 1:1 to production..

@nahuhh

nahuhh commented Jun 20, 2026

Copy link
Copy Markdown

real PoW, nothing mocked away. It's 1:1 to production..

they both use real pow, but testnet uses v1 transactions, and probably not even randomx?

@napoly

napoly commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

no need for randomx here.. i just need to pay for the invoice.. should be easy to switch/modify if we would need it tho

@nahuhh

nahuhh commented Jun 20, 2026

Copy link
Copy Markdown

Yea.. you said that regtest doesnt use pow.. it does.. and, it uses the same pow as mainnet.

it also uses the same type of transactions.

your old setup had a fixed difficulty of 1, the new setup has a fixed difficulty of 100. They both use pow

@napoly

napoly commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

but I also said it's 1:1 to prod.. testnet wont allow you to mine instantly for example.. (saves headache)

@nahuhh

nahuhh commented Jun 20, 2026

Copy link
Copy Markdown

testnet wont allow you to mine instantly

yes it will.. you changed the difficulty from 1 on regtest to 150 on testnet

@napoly

napoly commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

yes.. to 150.. so it wont

@napoly
napoly force-pushed the switch-to-private-testnet branch from cab1802 to 51d0631 Compare July 15, 2026 08:32
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4fe74f6a-9f7a-42d3-9a4e-a63157d69166

📥 Commits

Reviewing files that changed from the base of the PR and between 51d0631 and b069001.

📒 Files selected for processing (3)
  • BTCPayServer.Plugins.IntegrationTests/Monero/IntegrationTestUtils.cs
  • BTCPayServer.Plugins.IntegrationTests/Monero/MoneroPluginIntegrationTest.cs
  • BTCPayServer.Plugins.IntegrationTests/docker-compose.yml

📝 Walkthrough

Walkthrough

The integration test environment now runs two Monero daemon nodes, routes the wallet through the second node, updates service dependencies and volumes, and replaces hardcoded wallet addresses and private view keys in RPC and UI test setup.

Changes

Monero integration test environment

Layer / File(s) Summary
Two-node Monero test topology
BTCPayServer.Plugins.IntegrationTests/docker-compose.yml
The compose setup adds node_1 and node_2, routes test and wallet traffic through the new hosts, updates service dependencies and commands, bumps Postgres, and separates node data volumes.
Wallet key fixture alignment
BTCPayServer.Plugins.IntegrationTests/Monero/IntegrationTestUtils.cs, BTCPayServer.Plugins.IntegrationTests/Monero/MoneroPluginIntegrationTest.cs
RPC wallet generation and Playwright inputs use updated Monero address and private view key values while preserving the existing test assertions.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: deverickapollo

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: moving the Monero test setup to a private testnet and performing related upgrades.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (3)
BTCPayServer.Plugins.IntegrationTests/docker-compose.yml (2)

26-32: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

dev service pins a very old, EOL alpine:3.7 (2017) base image.

Not used by the test run itself, but anyone invoking docker-compose up dev gets a long-unsupported base. Consider a current alpine tag instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@BTCPayServer.Plugins.IntegrationTests/docker-compose.yml` around lines 26 -
32, Update the dev service image in the Docker Compose configuration from the
EOL alpine:3.7 tag to a currently supported Alpine tag, leaving the service
command and dependencies unchanged.

110-111: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Consider pinning to the latest 18.x patch instead of 18.1.

PostgreSQL 18.4, 17.10, 16.14, 15.18, and 14.23 were released May 14, 2026, and each subsequent minor release included security fixes over 18.1 (e.g. "an update to all supported versions of PostgreSQL, including 18.1, 17.7, 16.11, 15.15, 14.20, and 13.23" that "fixes 2 security vulnerabilities and over 50 bugs"). Since this is a fresh pin (not an in-place upgrade), bumping straight to the latest 18.x patch costs nothing extra.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@BTCPayServer.Plugins.IntegrationTests/docker-compose.yml` around lines 110 -
111, Update the PostgreSQL image tag in the docker-compose service from 18.1 to
the latest available 18.x patch release, keeping the existing postgres service
configuration unchanged.
BTCPayServer.Plugins.IntegrationTests/Monero/IntegrationTestUtils.cs (1)

246-247: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the shared test Monero address/view-key into one constant. The same raw testnet address + view-key literal is duplicated across 5 locations in 2 files; past reviews already flagged this repeatedly ("Same"). Every key rotation (like this testnet swap) has to be edited in lockstep across all sites, which is exactly what happened here and is easy to get wrong.

  • BTCPayServer.Plugins.IntegrationTests/Monero/IntegrationTestUtils.cs#L246-L247: define internal const string TestPrimaryAddress and TestPrivateViewKey here (or in a shared test fixtures class) and reference them from the generate_from_keys request params.
  • BTCPayServer.Plugins.IntegrationTests/Monero/MoneroPluginIntegrationTest.cs#L43-L45: replace the literal FillAsync arguments with the shared constants.
  • BTCPayServer.Plugins.IntegrationTests/Monero/MoneroPluginIntegrationTest.cs#L124-L124: replace the literal FillAsync argument with the shared view-key constant.
  • BTCPayServer.Plugins.IntegrationTests/Monero/MoneroPluginIntegrationTest.cs#L146-L147: replace the GenerateFromKeysRequest.PrimaryAddress/PrivateViewKey literals with the shared constants.
  • BTCPayServer.Plugins.IntegrationTests/Monero/MoneroPluginIntegrationTest.cs#L157-L159: replace the literal FillAsync arguments with the shared constants.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@BTCPayServer.Plugins.IntegrationTests/Monero/IntegrationTestUtils.cs` around
lines 246 - 247, Extract the duplicated Monero test address and view key into
internal constants named TestPrimaryAddress and TestPrivateViewKey near the
generate_from_keys request parameters in
BTCPayServer.Plugins.IntegrationTests/Monero/IntegrationTestUtils.cs (anchor
lines 246-247). Replace the literals with these constants in
MoneroPluginIntegrationTest.cs at lines 43-45, 124, 146-147, and 157-159,
including FillAsync calls and GenerateFromKeysRequest fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@BTCPayServer.Plugins.IntegrationTests/docker-compose.yml`:
- Around line 33-51: Update the --block-notify configuration in the node_1
monerod command to target node_2, matching the daemon used by xmr_wallet.
Preserve the existing callback URL and notification arguments while replacing
the notifier source so wallet confirmations remain synchronized.

---

Nitpick comments:
In `@BTCPayServer.Plugins.IntegrationTests/docker-compose.yml`:
- Around line 26-32: Update the dev service image in the Docker Compose
configuration from the EOL alpine:3.7 tag to a currently supported Alpine tag,
leaving the service command and dependencies unchanged.
- Around line 110-111: Update the PostgreSQL image tag in the docker-compose
service from 18.1 to the latest available 18.x patch release, keeping the
existing postgres service configuration unchanged.

In `@BTCPayServer.Plugins.IntegrationTests/Monero/IntegrationTestUtils.cs`:
- Around line 246-247: Extract the duplicated Monero test address and view key
into internal constants named TestPrimaryAddress and TestPrivateViewKey near the
generate_from_keys request parameters in
BTCPayServer.Plugins.IntegrationTests/Monero/IntegrationTestUtils.cs (anchor
lines 246-247). Replace the literals with these constants in
MoneroPluginIntegrationTest.cs at lines 43-45, 124, 146-147, and 157-159,
including FillAsync calls and GenerateFromKeysRequest fields.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bd817b14-3bc9-4c64-b1e9-984527d616e6

📥 Commits

Reviewing files that changed from the base of the PR and between 8e77d6c and 51d0631.

📒 Files selected for processing (3)
  • BTCPayServer.Plugins.IntegrationTests/Monero/IntegrationTestUtils.cs
  • BTCPayServer.Plugins.IntegrationTests/Monero/MoneroPluginIntegrationTest.cs
  • BTCPayServer.Plugins.IntegrationTests/docker-compose.yml

Comment thread BTCPayServer.Plugins.IntegrationTests/docker-compose.yml
@napoly
napoly force-pushed the switch-to-private-testnet branch from 51d0631 to fe248f1 Compare July 15, 2026 08:50
@napoly
napoly force-pushed the switch-to-private-testnet branch from fe248f1 to b069001 Compare July 15, 2026 09:44
@coderabbitai coderabbitai Bot mentioned this pull request Jul 16, 2026
@deverickapollo

Copy link
Copy Markdown
Member

One feature regtest offers is the ability to mine a number of blocks deterministically. I would expect this to be useful for tests. What feature of testnet is driving the switch here? It's not currently clear to me why we would move.

https://docs.getmonero.org/rpc-library/monerod-rpc/#generateblocks

@napoly

napoly commented Jul 24, 2026

Copy link
Copy Markdown
Member Author

Regtest is not realistic so it is a bit dangerous when one is trying to make a realistic copy of mainnet for a proper integration test bed. This change ain't written in a bible tho.. thus we can change later based on our needs. I needed this to simulate additional payments, which I was able to do.

@nahuhh

nahuhh commented Jul 24, 2026

Copy link
Copy Markdown

Regtest is not realistic so it is a bit dangerous when one is trying to make a realistic copy of mainnet for a proper integration test bed.

Again, this is wrong. Unless you run modified daemon build with an updated hardfork table, you are NOT running a realistic copy of mainnet - you are running a copy of v1 monero.
Regtest IS a realistic copy of mainnet - it's %he whole point of regtest. (minus tail emission, but private-testnet also does not have an active tail)

@napoly

napoly commented Jul 24, 2026

Copy link
Copy Markdown
Member Author

I switched to testnet so nobody after me would have a brilliant idea of instant mining and yet.. couple comments later we miss this feature.. have you folks seen such an ability on mainnet..? I did not.. to prevent anyone to go this direction I decided to switch.. (this have been working for haveno for years now) correct me if I'm wrong but if smthng works on v1 it should work on v16 (unless hard fork occurred)

@nahuhh

nahuhh commented Jul 24, 2026

Copy link
Copy Markdown

I switched to testnet so nobody after me would have a brilliant idea of instant mining

Instant mining works on a private test/stage/main/regtest. You have to send --fixed-difficulty=1 for that. Regtest difficulty raises just like testnet if you dont set a static difficulty.

You, yourself, set a difficulty of 150 on your private testnet for this very reason.

and yet.. couple comments later we miss this feature.. have you folks seen such an ability on mainnet..? I did not.. to prevent anyone to go this direction I decided to switch.. (this have been working for haveno for years now)

Basicswap has been using regtest for years as well. (Haveno also has a modified hardfork table.)

correct me if I'm wrong but if smthng works on v1 it should work on v16 (unless hard fork occurred)

each of those versions is a hard fork, and no, not everything from v1 works on v16 - thats the point of the hard forks. v14 transactions (11 ring members, no view tag) dont even work on v16.

v1 doesnt have ringct (it has transparent amounts and bucketing), bulletproofs (or bp+), randomx, the list goes on.

Again, haveno uses a modified HF table

@napoly

napoly commented Jul 24, 2026

Copy link
Copy Markdown
Member Author

We can modify the table as well if needed.

@nahuhh

nahuhh commented Jul 24, 2026

Copy link
Copy Markdown

We can modify the table as well if needed.

So you'd rather needlessly build a custom monerod daemon, creates coinbases from each hard fork, etc, just so that you can use testnet addresses? Because there is, afaict, zero reason to prefer a private-testnet over regtest

@napoly

napoly commented Jul 24, 2026

Copy link
Copy Markdown
Member Author

Because there is, afaict, zero reason to prefer a private-testnet over regtest

just wrote you reason..

So you'd rather needlessly build a custom monerod daemon

No.. not really.. I just want to fix production bug - additional payments.. nothing more.. once that is done we should focus on fees for example.. and I don't know yet but there is a change that the fees would be much better suited for regtest as one can easily mock/stub there.. but for now this feels like the best option to me.. and it's a minor thingy

@napoly
napoly merged commit 61ea08f into btcpay-monero:master Jul 25, 2026
6 checks passed
@napoly
napoly deleted the switch-to-private-testnet branch July 25, 2026 07:23
@deverickapollo

Copy link
Copy Markdown
Member

This should be regtest Napoly. Comments clearly state this. You have now ignored and merged.

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.

3 participants