Uploaded image for project: 'Corda'
  1. CORDA-2775

The DJVM cannot sandbox instances of Contract.verify(LedgerTransaction) when testing CorDapps.

    Details

    • Type: Bug
    • Status: Open (View workflow)
    • Priority: Medium
    • Resolution: Unresolved
    • Affects versions: Corda 4
    • Fix versions: Corda 4.1
    • Components: None
    • Labels:
      None
    • Severity:
      Medium
    • Feature Team:
      SGX
    • Sprint:

      Description

      Someone on the Public Slack channel was struggling to use the DJVM 4.0 library artifact. In part, this was due to them assuming that Corda and the DJVM were more integrated than they really were. However, using the DJVM was still more complicated than it needed to be.

      In effect, they were trying to do something like this:

      class SandboxExecutorTest : TestBase() {
          private val txID = SecureHash.allOnesHash
      
          @Test
          fun `can load and execute contract`() = sandbox(DEFAULT) {
              val salt = ByteArray(32)
              Random().nextBytes(salt)
              val tx = LedgerTransaction(
                  emptyList(),
                  emptyList(),
                  emptyList(),
                  emptyList(),
                  txID,
                  null,
                  null,
                  PrivacySalt(salt)
              )
              val contractExecutor = DeterministicSandboxExecutor<LedgerTransaction, Unit>(configuration)
              assertThatExceptionOfType(SandboxException::class.java)
                  .isThrownBy { contractExecutor.run<ContractWrapper>(tx) }
                  .withCauseInstanceOf(IllegalArgumentException::class.java)
                  .withMessageContaining("Contract constraint violated: txId=$txID")
          }
      
          class ContractWrapper : java.util.function.Function<LedgerTransaction, Unit> {
              override fun apply(tx: LedgerTransaction) {
                  ContractImpl().verify(tx)
              }
          }
      }
      
      class ContractImpl : Contract {
          override fun verify(tx: LedgerTransaction) {
              throw IllegalArgumentException("Contract constraint violated: txId=${tx.id}")
          }
      }
      

      with a TestBase class largely cloned from the DJVM project. This fails because corda-core-deterministic depends on Bouncy Castle, and some of the Bouncy Castle classes depend on classes that no longer exist inside deterministic-rt.jar:

      net.corda.djvm.rewiring.SandboxClassLoadingException: Failed to load class
       - [ERROR] Class file not found; java/io/ObjectInputStream.class
       - [ERROR] Class file not found; java/io/ObjectOutputStream.class
       - [ERROR] Class file not found; java/nio/channels/FileChannel.class
      

      Even if Bouncy Castle were transformable, the above example would still fail because we cannot currently sandbox / unsandbox instances of LedgerTransaction - which we would need to do before we could pass an instance as an argument to

      Function.apply(input)
      

        Attachments

          Activity

            People

            • Assignee:
              chris.rankin Chris Rankin
              Reporter:
              chris.rankin Chris Rankin
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated: