Deprecated: Function get_magic_quotes_gpc() is deprecated in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 99

Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 619

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1169

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176
10BC0 Ensure that a CorDapp is present in cordapps directory when choosing an attachment for a missing class dependency by Tagada14 · Pull Request #7994 · corda/corda · GitHub
Nothing Special   »   [go: up one dir, main page]

Skip to content

Conversation

Tagada14
Copy link
@Tagada14 Tagada14 commented Sep 12, 2025

Problem description:

When building a transaction, the TransactionBuilder attempts to verify a transaction, and if it encounters a missing class dependency, it looks for it in the attachments and adds the attachment with the missing class to the transaction. However, it considers all of the attachments from the Attachment Storage rather than the CorDapps present in the node. This allows it to add an arbitrary trusted attachment that contains the missing class, even a legacy one! Moreover, it doesn't check if multiple attachments contain said class; it simply chooses the first one. Because of this, the attachment it chooses is runtime-dependent and non-deterministic. With the same set of attachments in the storage, one node may attach CorDapp A with the missing class and the other CorDapp B.

Implemented solution:

When fetching potential attachments which contain the missing class, we only consider the ones that are part of the cordapps folder in our node. We also check that only one such CorDapp is found to ensure deterministic behaviour.
For the legacy part of the transaction, we relax this requirement to maintain backwards compatibility, as existing CorDapps are already using this functionality.

PR Checklist:

  • Have you run the unit, integration and smoke tests as described here?
  • If you added public APIs, did you write the JavaDocs/kdocs?
  • If the changes are of interest to application developers, have you added them to the changelog, and potentially the release notes (https://docs.r3.com/release-notes.html)?
  • If you are contributing for the first time, please read the contributor agreement now and add a comment to this pull request stating that your PR is in accordance with the Developer's Certificate of Origin.

Thanks for your code, it's appreciated! :)

…chments present in the cordapp directory. Enforce that only one of them may contain the dependency to ensure deterministic behaviour.
@Tagada14 Tagada14 requested a review from rick-r3 as a code owner September 12, 2025 12:41
@Tagada14
Copy link
Author

I hereby certify that my contribution is in accordance with the Developer Certificate of Origin.

@Tagada14
Copy link
Author

Tests are still running locally, will report back the result once they finish.
I haven't added any public APIs.
The changes are very much of interest to application developers. The functionality of adding a missing class is not described anywhere in the docs, and was poorly designed from the beginning. Same for how to properly add a dependency on a CorDapp or non-CorDapp that do not contain the contracts used in the transaction. I urge you to describe those features in detail in the docs and write an update in the release notes.

@Tagada14
Copy link
Author

I've also created a quick test to reproduce the bug I've discovered when preparing a release of our application using Corda 4.12. Here is a test case that can be added to TransactionBuilderDriverTest.kt that shows that a legacy CorDapp may be attached to a non-legacy part of a transaction.

@Test(timeout = 300_000)
fun `test`() {
    internalDriver(
            cordappsForAllNodes = listOf(FINANCE_WORKFLOWS_CORDAPP),
            startNodesInProcess = false,
            networkParameters = testNetworkParameters(minimumPlatformVersion = 4),
            notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, validating = false))
    ) {
        val (cordapp, dependency) = splitFinanceContractCordapp(currentFinanceContractsJar)
        val legacyContracts = TestCordapp.of(legacyFinanceContractsJar.toUri()).asSigned() as TestCordappInternal

        cordapp.jarFile.inputStream().use(defaultNotaryNode.getOrThrow().rpc::uploadAttachment)
        dependency.jarFile.inputStream().use(defaultNotaryNode.getOrThrow().rpc::uploadAttachment)

        val node = startNode(NodeParameters(
                ALICE_NAME,
                additionalCordapps = listOf(cordapp),
                legacyContracts = listOf(legacyContracts)
        )).getOrThrow()

        val stx = createTransaction(node)
        assertThat(stx.tx.attachments).contains(legacyContracts.jarFile.hash)
    }
}

@Tagada14
Copy link
Author

All of the tests from the test suite and the integration test suite passed. I'm having issues with some of the smoke tests, specifically ExternalVerificationTests, due to the Java version. All of the other smoke tests passed.

@adelel1
Copy link
Collaborator
adelel1 commented Oct 10, 2025

Hi @Tagada14 Thank you for your contribution here. It is very much appreciated. We will shortly be looking into this. Will update support ticket if further information needed.

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

0