mirror of
https://github.com/corda/corda.git
synced 2025-01-18 10:46:38 +00:00
Revert design changes to attachment demo (#540)
Restructure attachment demo Restructure attachment demo to pass the attachment hash in the transaction outputs, rather than trying to use shared memory. Also remove 1kb test for attachments as there's little value in having a smaller test case.
This commit is contained in:
parent
8e0a0ba8fb
commit
022b38b7dc
@ -13,18 +13,9 @@ import org.junit.Test
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
class AttachmentDemoTest {
|
||||
// run with the default 1K bytes in-memory zip file.
|
||||
@Test fun `attachment demo`() {
|
||||
attachmentDemo()
|
||||
}
|
||||
|
||||
// run with a 10,000,000 bytes in-memory zip file. In practice, a slightly bigger file will be used (~10,002,000 bytes).
|
||||
@Test fun `attachment demo using a 10MB zip file`() {
|
||||
attachmentDemo(10000000)
|
||||
}
|
||||
|
||||
// An in-memory zip file will be used as InputStream, with a size slightly bigger than numOfExpectedBytes.
|
||||
private fun attachmentDemo(numOfExpectedBytes: Int = 1024) {
|
||||
val numOfExpectedBytes = 10_000_000
|
||||
driver(dsl = {
|
||||
val demoUser = listOf(User("demo", "demo", setOf("StartFlow.net.corda.flows.FinalityFlow")))
|
||||
val (nodeA, nodeB) = Futures.allAsList(
|
||||
|
@ -3,21 +3,22 @@ package net.corda.attachmentdemo
|
||||
import com.google.common.net.HostAndPort
|
||||
import joptsimple.OptionParser
|
||||
import net.corda.client.rpc.CordaRPCClient
|
||||
import net.corda.core.contracts.Contract
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.contracts.TransactionForContract
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.div
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.messaging.CordaRPCOps
|
||||
import net.corda.core.messaging.startFlow
|
||||
import net.corda.core.sizedInputStreamAndHash
|
||||
import net.corda.core.utilities.ALICE_KEY
|
||||
import net.corda.core.utilities.DUMMY_NOTARY
|
||||
import net.corda.core.utilities.DUMMY_NOTARY_KEY
|
||||
import net.corda.core.utilities.Emoji
|
||||
import net.corda.flows.FinalityFlow
|
||||
import net.corda.nodeapi.config.SSLConfiguration
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.security.PublicKey
|
||||
import kotlin.system.exitProcess
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -57,8 +58,6 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
var EXPECTED_HASH = SecureHash.zeroHash // Note: We could use another random default value to initialize it.
|
||||
|
||||
/** An in memory test zip attachment of at least numOfClearBytes size, will be used. */
|
||||
fun sender(rpc: CordaRPCOps, numOfClearBytes: Int = 1024) { // default size 1K.
|
||||
val (inputStream, hash) = sizedInputStreamAndHash(numOfClearBytes)
|
||||
@ -66,7 +65,6 @@ fun sender(rpc: CordaRPCOps, numOfClearBytes: Int = 1024) { // default size 1K.
|
||||
}
|
||||
|
||||
fun sender(rpc: CordaRPCOps, inputStream: InputStream, hash: SecureHash.SHA256) {
|
||||
EXPECTED_HASH = hash
|
||||
// Get the identity key of the other side (the recipient).
|
||||
val otherSide: Party = rpc.partyFromName("Bank B")!!
|
||||
|
||||
@ -78,15 +76,14 @@ fun sender(rpc: CordaRPCOps, inputStream: InputStream, hash: SecureHash.SHA256)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a trivial transaction that just passes across the attachment - in normal cases there would be
|
||||
// inputs, outputs and commands that refer to this attachment.
|
||||
val ptx = TransactionType.General.Builder(notary = null)
|
||||
// Create a trivial transaction with an output that describes the attachment, and the attachment itself
|
||||
val ptx = TransactionType.General.Builder(notary = DUMMY_NOTARY)
|
||||
require(rpc.attachmentExists(hash))
|
||||
ptx.addOutputState(AttachmentContract.State(hash))
|
||||
ptx.addAttachment(hash)
|
||||
// TODO: Add a dummy state and specify a notary, so that the tx hash is randomised each time and the demo can be repeated.
|
||||
|
||||
// Despite not having any states, we have to have at least one signature on the transaction
|
||||
ptx.signWith(ALICE_KEY)
|
||||
// Sign with the notary key
|
||||
ptx.signWith(DUMMY_NOTARY_KEY)
|
||||
|
||||
// Send the transaction to the other recipient
|
||||
val stx = ptx.toSignedTransaction()
|
||||
@ -101,9 +98,13 @@ fun recipient(rpc: CordaRPCOps) {
|
||||
val stx = rpc.verifiedTransactions().second.toBlocking().first()
|
||||
val wtx = stx.tx
|
||||
if (wtx.attachments.isNotEmpty()) {
|
||||
assertEquals(EXPECTED_HASH, wtx.attachments.first())
|
||||
require(rpc.attachmentExists(EXPECTED_HASH))
|
||||
println("File received - we're happy!\n\nFinal transaction is:\n\n${Emoji.renderIfSupported(wtx)}")
|
||||
if (wtx.outputs.isNotEmpty()) {
|
||||
val state = wtx.outputs.map { it.data }.filterIsInstance<AttachmentContract.State>().single()
|
||||
require(rpc.attachmentExists(state.hash))
|
||||
println("File received - we're happy!\n\nFinal transaction is:\n\n${Emoji.renderIfSupported(wtx)}")
|
||||
} else {
|
||||
println("Error: no output state found in ${wtx.id}")
|
||||
}
|
||||
} else {
|
||||
println("Error: no attachments found in ${wtx.id}")
|
||||
}
|
||||
@ -118,11 +119,18 @@ private fun printHelp(parser: OptionParser) {
|
||||
parser.printHelpOn(System.out)
|
||||
}
|
||||
|
||||
// TODO: Take this out once we have a dedicated RPC port and allow SSL on it to be optional.
|
||||
private fun sslConfigFor(nodename: String, certsPath: String?): SSLConfiguration {
|
||||
return object : SSLConfiguration {
|
||||
override val keyStorePassword: String = "cordacadevpass"
|
||||
override val trustStorePassword: String = "trustpass"
|
||||
override val certificatesDirectory: Path = if (certsPath != null) Paths.get(certsPath) else Paths.get("build") / "nodes" / nodename / "certificates"
|
||||
class AttachmentContract : Contract {
|
||||
override val legalContractReference: SecureHash
|
||||
get() = TODO("not implemented")
|
||||
|
||||
override fun verify(tx: TransactionForContract) {
|
||||
val state = tx.outputs.filterIsInstance<AttachmentContract.State>().single()
|
||||
val attachment = tx.attachments.single()
|
||||
require(state.hash == attachment.id)
|
||||
}
|
||||
}
|
||||
|
||||
data class State(val hash: SecureHash.SHA256) : ContractState {
|
||||
override val contract: Contract = AttachmentContract()
|
||||
override val participants: List<PublicKey> = emptyList()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user