Fixed Enclavelet

This commit is contained in:
sollecitom 2017-09-27 15:05:18 +01:00
parent 85bc0a38a2
commit 3f5561db1e
4 changed files with 26 additions and 15 deletions

View File

@ -1,5 +1,6 @@
package com.r3.enclaves.verify package com.r3.enclaves.verify
import com.r3.enclaves.txverify.MockContractAttachment
import com.r3.enclaves.txverify.NativeSgxApi import com.r3.enclaves.txverify.NativeSgxApi
import com.r3.enclaves.txverify.TransactionVerificationRequest import com.r3.enclaves.txverify.TransactionVerificationRequest
import net.corda.core.identity.AnonymousParty import net.corda.core.identity.AnonymousParty
@ -21,8 +22,6 @@ class NativeSgxApiTest {
val enclavePath = "../sgx-jvm/jvm-enclave/enclave/build/cordaenclave.signed.so" 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") @Ignore("The SGX code is not part of the standard build yet")
@Test @Test
fun `verification of valid transaction works`() { fun `verification of valid transaction works`() {
@ -48,8 +47,8 @@ class NativeSgxApiTest {
command(MEGA_CORP_PUBKEY, Cash.Commands.Move()) command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
verifies() verifies()
} }
val cashContract = MockContractAttachment(interpreter.services.cordappProvider.getContractAttachmentID(Cash.PROGRAM_ID)!!, Cash.PROGRAM_ID)
val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(stubbedCashContractBytes)) val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(cashContract.serialize().bytes))
val serialized = req.serialize() val serialized = req.serialize()
assertNull(NativeSgxApi.verify(enclavePath, serialized.bytes)) assertNull(NativeSgxApi.verify(enclavePath, serialized.bytes))
} }

View File

@ -3,13 +3,11 @@
package com.r3.enclaves.txverify package com.r3.enclaves.txverify
import com.esotericsoftware.minlog.Log import com.esotericsoftware.minlog.Log
import net.corda.core.contracts.HashAttachmentConstraint import net.corda.core.contracts.Attachment
import net.corda.core.crypto.sha256
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.transactions.WireTransaction import net.corda.core.transactions.WireTransaction
import net.corda.nodeapi.internal.serialization.GeneratedAttachment
import java.io.File import java.io.File
// This file implements the functionality of the SGX transaction verification enclave. // This file implements the functionality of the SGX transaction verification enclave.
@ -35,11 +33,14 @@ fun verifyInEnclave(reqBytes: ByteArray) {
val req = reqBytes.deserialize<TransactionVerificationRequest>() val req = reqBytes.deserialize<TransactionVerificationRequest>()
val wtxToVerify = req.wtxToVerify.deserialize() val wtxToVerify = req.wtxToVerify.deserialize()
val dependencies = req.dependencies.map { it.deserialize() }.associateBy { it.id } val dependencies = req.dependencies.map { it.deserialize() }.associateBy { it.id }
val attachments = req.attachments.map { it.deserialize<Attachment>() }
val attachmentMap = attachments.associateBy(Attachment::id)
val contractAttachmentMap = attachments.mapNotNull { it as? MockContractAttachment }.associateBy { it.contract }
val ltx = wtxToVerify.toLedgerTransaction( val ltx = wtxToVerify.toLedgerTransaction(
resolveIdentity = { null }, 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) }, resolveStateRef = { dependencies[it.txhash]?.outputs?.get(it.index) },
resolveContractAttachment = { (it.constraint as HashAttachmentConstraint).attachmentId } resolveContractAttachment = { contractAttachmentMap[it.contract]?.id }
) )
ltx.verify() ltx.verify()
} }

View File

@ -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<Party> = ArrayList()) : Attachment {
override fun open() = ByteArrayInputStream(id.bytes)
}

View File

@ -17,9 +17,6 @@ import kotlin.test.assertFailsWith
import kotlin.test.assertTrue import kotlin.test.assertTrue
class EnclaveletTest { class EnclaveletTest {
private val stubbedCashContractBytes = Cash.PROGRAM_ID.toByteArray()
@Test @Test
fun success() { fun success() {
ledger { ledger {
@ -44,7 +41,8 @@ class EnclaveletTest {
command(MEGA_CORP_PUBKEY, Cash.Commands.Move()) command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
verifies() 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() val serialized = req.serialize()
Files.write(Paths.get("/tmp/req"), serialized.bytes) Files.write(Paths.get("/tmp/req"), serialized.bytes)
verifyInEnclave(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))) 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") failsWith("Required ${Cash.Commands.Move::class.java.canonicalName} command")
} }
// TODO need to add the CashContract Attachment Bytes val cashContract = MockContractAttachment(interpreter.services.cordappProvider.getContractAttachmentID(Cash.PROGRAM_ID)!!, Cash.PROGRAM_ID)
val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(stubbedCashContractBytes)) val req = TransactionVerificationRequest(wtx3.serialize(), arrayOf(wtx1.serialize(), wtx2.serialize()), arrayOf(cashContract.serialize().bytes))
val e = assertFailsWith<Exception> { verifyInEnclave(req.serialize().bytes) } val e = assertFailsWith<Exception> { verifyInEnclave(req.serialize().bytes) }
assertTrue(e.message!!.contains("Required ${Cash.Commands.Move::class.java.canonicalName} command")) assertTrue(e.message!!.contains("Required ${Cash.Commands.Move::class.java.canonicalName} command"))
} }