From 3f5561db1efde201e270b7e07e2b3e056b447fd3 Mon Sep 17 00:00:00 2001 From: sollecitom Date: Wed, 27 Sep 2017 15:05:18 +0100 Subject: [PATCH] Fixed Enclavelet --- .../com/r3/enclaves/verify/NativeSgxApiTest.kt | 7 +++---- .../kotlin/com/r3/enclaves/txverify/Enclavelet.kt | 11 ++++++----- .../r3/enclaves/txverify/MockContractAttachment.kt | 13 +++++++++++++ .../com/r3/enclaves/txverify/EnclaveletTest.kt | 10 ++++------ 4 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 verify-enclave/src/main/kotlin/com/r3/enclaves/txverify/MockContractAttachment.kt diff --git a/verify-enclave/src/integration-test/kotlin/com/r3/enclaves/verify/NativeSgxApiTest.kt b/verify-enclave/src/integration-test/kotlin/com/r3/enclaves/verify/NativeSgxApiTest.kt index 87d878fa8a..2b8b244215 100644 --- a/verify-enclave/src/integration-test/kotlin/com/r3/enclaves/verify/NativeSgxApiTest.kt +++ b/verify-enclave/src/integration-test/kotlin/com/r3/enclaves/verify/NativeSgxApiTest.kt @@ -1,5 +1,6 @@ package com.r3.enclaves.verify +import com.r3.enclaves.txverify.MockContractAttachment import com.r3.enclaves.txverify.NativeSgxApi import com.r3.enclaves.txverify.TransactionVerificationRequest import net.corda.core.identity.AnonymousParty @@ -21,8 +22,6 @@ class NativeSgxApiTest { val enclavePath = "../sgx-jvm/jvm-enclave/enclave/build/cordaenclave.signed.so" } - private val stubbedCashContractBytes = Cash.PROGRAM_ID.toByteArray() - @Ignore("The SGX code is not part of the standard build yet") @Test fun `verification of valid transaction works`() { @@ -48,8 +47,8 @@ class NativeSgxApiTest { command(MEGA_CORP_PUBKEY, Cash.Commands.Move()) verifies() } - - val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(stubbedCashContractBytes)) + val cashContract = MockContractAttachment(interpreter.services.cordappProvider.getContractAttachmentID(Cash.PROGRAM_ID)!!, Cash.PROGRAM_ID) + val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(cashContract.serialize().bytes)) val serialized = req.serialize() assertNull(NativeSgxApi.verify(enclavePath, serialized.bytes)) } diff --git a/verify-enclave/src/main/kotlin/com/r3/enclaves/txverify/Enclavelet.kt b/verify-enclave/src/main/kotlin/com/r3/enclaves/txverify/Enclavelet.kt index b01f291c43..aa7b785ca9 100644 --- a/verify-enclave/src/main/kotlin/com/r3/enclaves/txverify/Enclavelet.kt +++ b/verify-enclave/src/main/kotlin/com/r3/enclaves/txverify/Enclavelet.kt @@ -3,13 +3,11 @@ package com.r3.enclaves.txverify import com.esotericsoftware.minlog.Log -import net.corda.core.contracts.HashAttachmentConstraint -import net.corda.core.crypto.sha256 +import net.corda.core.contracts.Attachment import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.deserialize import net.corda.core.transactions.WireTransaction -import net.corda.nodeapi.internal.serialization.GeneratedAttachment import java.io.File // This file implements the functionality of the SGX transaction verification enclave. @@ -35,11 +33,14 @@ fun verifyInEnclave(reqBytes: ByteArray) { val req = reqBytes.deserialize() val wtxToVerify = req.wtxToVerify.deserialize() val dependencies = req.dependencies.map { it.deserialize() }.associateBy { it.id } + val attachments = req.attachments.map { it.deserialize() } + val attachmentMap = attachments.associateBy(Attachment::id) + val contractAttachmentMap = attachments.mapNotNull { it as? MockContractAttachment }.associateBy { it.contract } val ltx = wtxToVerify.toLedgerTransaction( resolveIdentity = { null }, - resolveAttachment = { secureHash -> req.attachments.filter { it.sha256() == secureHash }.map { GeneratedAttachment(it) }.singleOrNull() }, + resolveAttachment = { attachmentMap[it] }, resolveStateRef = { dependencies[it.txhash]?.outputs?.get(it.index) }, - resolveContractAttachment = { (it.constraint as HashAttachmentConstraint).attachmentId } + resolveContractAttachment = { contractAttachmentMap[it.contract]?.id } ) ltx.verify() } diff --git a/verify-enclave/src/main/kotlin/com/r3/enclaves/txverify/MockContractAttachment.kt b/verify-enclave/src/main/kotlin/com/r3/enclaves/txverify/MockContractAttachment.kt new file mode 100644 index 0000000000..79264cf647 --- /dev/null +++ b/verify-enclave/src/main/kotlin/com/r3/enclaves/txverify/MockContractAttachment.kt @@ -0,0 +1,13 @@ +package com.r3.enclaves.txverify + +import net.corda.core.contracts.Attachment +import net.corda.core.contracts.ContractClassName +import net.corda.core.crypto.SecureHash +import net.corda.core.identity.Party +import net.corda.core.serialization.CordaSerializable +import java.io.ByteArrayInputStream + +@CordaSerializable +class MockContractAttachment(override val id: SecureHash = SecureHash.zeroHash, val contract: ContractClassName, override val signers: List = ArrayList()) : Attachment { + override fun open() = ByteArrayInputStream(id.bytes) +} \ No newline at end of file diff --git a/verify-enclave/src/test/kotlin/com/r3/enclaves/txverify/EnclaveletTest.kt b/verify-enclave/src/test/kotlin/com/r3/enclaves/txverify/EnclaveletTest.kt index 7935d2d3be..329eb22b8e 100644 --- a/verify-enclave/src/test/kotlin/com/r3/enclaves/txverify/EnclaveletTest.kt +++ b/verify-enclave/src/test/kotlin/com/r3/enclaves/txverify/EnclaveletTest.kt @@ -17,9 +17,6 @@ import kotlin.test.assertFailsWith import kotlin.test.assertTrue class EnclaveletTest { - - private val stubbedCashContractBytes = Cash.PROGRAM_ID.toByteArray() - @Test fun success() { ledger { @@ -44,7 +41,8 @@ class EnclaveletTest { command(MEGA_CORP_PUBKEY, Cash.Commands.Move()) verifies() } - val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(stubbedCashContractBytes)) + val cashContract = MockContractAttachment(interpreter.services.cordappProvider.getContractAttachmentID(Cash.PROGRAM_ID)!!, Cash.PROGRAM_ID) + val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(cashContract.serialize().bytes)) val serialized = req.serialize() Files.write(Paths.get("/tmp/req"), serialized.bytes) verifyInEnclave(serialized.bytes) @@ -75,8 +73,8 @@ class EnclaveletTest { output(Cash.PROGRAM_ID, "c3", Cash.State(3000.POUNDS `issued by` DUMMY_CASH_ISSUER, AnonymousParty(MINI_CORP_PUBKEY))) failsWith("Required ${Cash.Commands.Move::class.java.canonicalName} command") } - // TODO need to add the CashContract Attachment Bytes - val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(stubbedCashContractBytes)) + val cashContract = MockContractAttachment(interpreter.services.cordappProvider.getContractAttachmentID(Cash.PROGRAM_ID)!!, Cash.PROGRAM_ID) + val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(cashContract.serialize().bytes)) val e = assertFailsWith { verifyInEnclave(req.serialize().bytes) } assertTrue(e.message!!.contains("Required ${Cash.Commands.Move::class.java.canonicalName} command")) }