Skip to content

Backward compatibility testing infrastructure#2031

Draft
darioAnongba wants to merge 6 commits intomainfrom
backward-compat-testing
Draft

Backward compatibility testing infrastructure#2031
darioAnongba wants to merge 6 commits intomainfrom
backward-compat-testing

Conversation

@darioAnongba
Copy link
Copy Markdown
Contributor

  • Wire format fixture tests (per-PR): Committed v0.8 wire format fixtures for rfqmsg (request, accept, reject, HTLC) and tapchannelmsg (funding blob, commitment blob, HTLC blob). Backward compat tests decode each fixture with current code and verify round-trip encoding on every PR.
  • Mixed-version integration test harness: Added NewNodeWithBinary and UpgradeNode to IntegratedNetworkHarness so tests can start nodes on older binaries and simulate upgrades mid-operation.
  • Build script for old binaries: scripts/build-compat-binary.sh builds tapd-integrated from any git tag using a temporary worktree and caches the result in ~/.tapd-compat-bins/.
  • Compat integration test wrapper: TestCustomChannelsCompat runs core, force close, and v1 upgrade tests against each configured historical version. The compatVersions list is empty until v0.8.0 is tagged.
  • Makefile targets + CI: make itest-cc-compat, make build-compat-binary, make gen-compat-fixtures. GitHub Actions workflow triggers on release/* pushes and workflow_dispatch.

Design

Two layers catch different classes of regressions:

Layer Runs on Catches Cost
Fixture decode tests Every PR Encoding/decoding wire format breaks ~seconds
Mixed-version itests Release branches + manual Runtime/interaction protocol bugs ~15 min

Bitcoin Core takes a similar approach (feature_backwards_compatibility.py on demand, not every PR) but their protocol evolves much more slowly.

Closes #2027

Add two methods to IntegratedNetworkHarness for backward compatibility
testing. NewNodeWithBinary starts a node with a specific binary path
(e.g. an older release), while UpgradeNode stops a node and restarts
it with the harness's default (current) binary, preserving data
directories.
Add a script that builds the tapd-integrated binary from a specific git
tag using a temporary worktree. Built binaries are cached locally so
subsequent invocations are instant. This supports backward compatibility
testing without requiring release artifact publishing.
Add wire format fixtures for v0.8 RFQ messages (request, accept, reject,
HTLC) and a backward compatibility test that decodes each fixture and
verifies round-trip encoding. Fixtures are generated deterministically
via the gen_test_vectors build tag and tested on every PR.
Add v0.8 wire format fixtures for channel messages (funding blob,
commitment blob, HTLC blob) organized under testdata/compat/v0.8/.
These are captured from real protocol interactions. A backward
compatibility test verifies that each fixture can be decoded by the
current code on every PR.
Add TestCustomChannelsCompat which runs a subset of custom channel tests
(core, force close, v1 upgrade) with one node running an older binary
for each configured historical version. The test builds old binaries
from source via build-compat-binary.sh and caches them locally.

The compatVersions list is initially empty with a TODO to populate once
v0.8.0 is released.
Add Makefile targets:
- itest-cc-compat: runs backward compat integration tests
- build-compat-binary: builds an old tapd-integrated from a git tag
- gen-compat-fixtures: regenerates wire format fixture files

Add a GitHub Actions workflow that triggers on release/* pushes and
manual dispatch to run the compat test suite with cached old binaries.
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a comprehensive backward compatibility testing framework to prevent regressions in wire format encoding/decoding and protocol interactions. It establishes two layers of testing: per-PR fixture decode tests for immediate feedback on wire format changes, and mixed-version integration tests for more thorough runtime and interaction protocol validation. This new infrastructure allows for testing against historical binary versions, simulating real-world upgrade scenarios, and ensuring the long-term stability and interoperability of the system.

Highlights

  • Wire Format Fixture Tests: Committed v0.8 wire format fixtures for rfqmsg (request, accept, reject, HTLC) and tapchannelmsg (funding blob, commitment blob, HTLC blob). These tests decode each fixture with current code and verify round-trip encoding on every PR.
  • Mixed-Version Integration Test Harness: Added NewNodeWithBinary and UpgradeNode to IntegratedNetworkHarness to enable tests to start nodes on older binaries and simulate mid-operation upgrades.
  • Build Script for Old Binaries: Introduced scripts/build-compat-binary.sh which builds tapd-integrated from any git tag using a temporary worktree and caches the result.
  • Compatibility Integration Test Wrapper: Added TestCustomChannelsCompat to run core, force close, and v1 upgrade tests against configured historical versions. This list will be populated once v0.8.0 is tagged.
  • Makefile Targets and CI Integration: Added new Makefile targets (itest-cc-compat, build-compat-binary, gen-compat-fixtures) and configured GitHub Actions workflow to trigger on release/* pushes and workflow_dispatch.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • Makefile
    • Added itest-cc-compat target for running backward compatibility integration tests.
    • Added build-compat-binary target for building specific version binaries.
    • Added gen-compat-fixtures target for generating backward compatibility fixtures.
  • itest/custom_channels/compat_test.go
    • Added new file containing TestCustomChannelsCompat for running compatibility integration tests against historical versions.
    • Implemented buildCompatBinary function to build or retrieve cached tapd-integrated binaries for specified versions.
    • Defined compatVersions and compatTestCases to manage historical versions and test scenarios.
  • itest/integrated_harness.go
    • Added NewNodeWithBinary method to create and start a new IntegratedNode using a specified binary path.
    • Added UpgradeNode method to simulate a node upgrade by restarting it with the harness's default binary while preserving data.
  • rfqmsg/backward_compat_test.go
    • Added new file containing TestBackwardCompatFixtures to verify decoding and round-trip encoding of historical RFQ wire format fixtures.
    • Implemented helper functions readHexFixture and individual test functions for request, accept, reject, and HTLC messages.
  • rfqmsg/compat_fixtures_test.go
    • Added new file containing TestGenerateCompatFixtures to generate deterministic wire format fixtures for RFQ message types.
    • Defined compatFixtureVersion and compatFixtureDir constants for fixture organization.
  • rfqmsg/testdata/compat/v0.8/accept.hex
    • Added hex-encoded fixture data for RFQ accept messages (v0.8).
  • rfqmsg/testdata/compat/v0.8/htlc.hex
    • Added hex-encoded fixture data for RFQ HTLC messages (v0.8).
  • rfqmsg/testdata/compat/v0.8/reject.hex
    • Added hex-encoded fixture data for RFQ reject messages (v0.8).
  • rfqmsg/testdata/compat/v0.8/request.hex
    • Added hex-encoded fixture data for RFQ request messages (v0.8).
  • scripts/build-compat-binary.sh
    • Added new script to build tapd-integrated from a specific git tag, with caching functionality.
  • tapchannelmsg/backward_compat_test.go
    • Added new file containing TestBackwardCompatFixtures to verify decoding of historical Taproot Asset Channel wire format fixtures.
    • Implemented helper functions testCompatFundingBlob, testCompatCommitmentBlob, and testCompatHtlcBlob.
  • tapchannelmsg/testdata/compat/v0.8/commitment-blob.hexdump
    • Added hexdump fixture data for Taproot Asset Channel commitment blobs (v0.8).
  • tapchannelmsg/testdata/compat/v0.8/funding-blob.hexdump
    • Added hexdump fixture data for Taproot Asset Channel funding blobs (v0.8).
  • tapchannelmsg/testdata/compat/v0.8/htlc-blob.hexdump
    • Added hexdump fixture data for Taproot Asset Channel HTLC blobs (v0.8).
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/compat.yaml
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a comprehensive backward compatibility testing framework, which is a great addition for ensuring protocol stability across versions. The implementation includes two layers of testing: wire format fixture tests and mixed-version integration tests. The new Makefile targets, test harness extensions for running nodes with different binaries, and the build script for old binaries are well-designed. I have one suggestion to improve the maintainability of the test code by avoiding the use of environment variables to pass state within tests.

Comment on lines +154 to +157
// Store the old binary path in the harness so test cases can
// retrieve it. We use an environment variable as a simple
// side channel.
t.Setenv("COMPAT_OLD_BINARY", oldBinary)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using environment variables to pass data between test setup and test cases can be brittle. A more robust approach would be to extend the ccHarnessTest struct to include the oldBinary path. This would make the data flow explicit and avoid potential issues with parallel test execution if not handled carefully, even though t.Setenv provides some protection.

For example:

// in this file
ht := &ccHarnessTest{
    t:          t1,
    testCase:   tc,
    lndHarness: net,
    oldBinary:  oldBinary, // new field
}

// in test files that need it
oldBinaryPath := ht.oldBinary
if oldBinaryPath != "" {
    // use NewNodeWithBinary
} else {
    // use NewNode
}

This would require modifying the ccHarnessTest struct and how it's used in the test cases, but it leads to cleaner and more maintainable test code.

@coveralls
Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 23209855627

Details

  • 0 of 32 (0.0%) changed or added relevant lines in 1 file are covered.
  • 33 unchanged lines in 7 files lost coverage.
  • Overall coverage increased (+0.01%) to 33.459%

Changes Missing Coverage Covered Lines Changed/Added Lines %
itest/integrated_harness.go 0 32 0.0%
Files with Coverage Reduction New Missed Lines %
address/mock.go 2 95.11%
asset/group_key.go 2 62.64%
tappsbt/create.go 2 22.71%
address/address.go 5 67.84%
tapchannel/aux_leaf_signer.go 5 43.18%
tapdb/multiverse.go 6 54.38%
tapgarden/caretaker.go 11 68.42%
Totals Coverage Status
Change from base Build 23145634447: 0.01%
Covered Lines: 33134
Relevant Lines: 99028

💛 - Coveralls

@darioAnongba darioAnongba changed the title Backward compat testing Backward compatibility testing infrastructure Mar 17, 2026
@darioAnongba darioAnongba moved this from 🆕 New to 🏗 In progress in Taproot-Assets Project Board Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: 🏗 In progress

Development

Successfully merging this pull request may close these issues.

Backwards compatibility validation

2 participants