From 1344bfd6bbed18b95d21535df71029ea86963014 Mon Sep 17 00:00:00 2001 From: sofusmortensen <sofusmortensen@gmail.com> Date: Wed, 23 Mar 2016 17:51:14 +0000 Subject: [PATCH] Replaced programRef in ContractState with a simple reference to contract --- .../kotlin/contracts/AnotherDummyContract.kt | 12 +++-- .../java/contracts/JavaCommercialPaper.java | 8 ++-- contracts/src/main/kotlin/contracts/Cash.kt | 5 ++- .../main/kotlin/contracts/CommercialPaper.kt | 4 +- .../src/main/kotlin/contracts/CrowdFund.kt | 4 +- .../main/kotlin/contracts/DummyContract.kt | 4 +- contracts/src/main/kotlin/contracts/IRS.kt | 4 +- core/src/main/kotlin/core/Structures.kt | 19 +------- .../kotlin/core/TransactionVerification.kt | 12 +++-- .../main/kotlin/core/serialization/Kryo.kt | 44 ++++++++++++++++++- src/main/kotlin/core/node/AbstractNode.kt | 23 ++-------- src/main/kotlin/core/node/ClassLoader.kt | 6 +++ .../kotlin/core/node/services/Services.kt | 7 +-- .../core/node/services/StorageServiceImpl.kt | 3 -- .../protocols/ResolveTransactionsProtocol.kt | 2 +- .../kotlin/contracts/CommercialPaperTests.kt | 4 +- src/test/kotlin/contracts/CrowdFundTests.kt | 4 +- src/test/kotlin/core/MockServices.kt | 10 +---- src/test/kotlin/core/TransactionGroupTests.kt | 2 +- .../messaging/TwoPartyTradeProtocolTests.kt | 5 +-- src/test/kotlin/core/node/ClassLoaderTests.kt | 5 +++ src/test/kotlin/core/testutils/TestUtils.kt | 6 +-- 22 files changed, 100 insertions(+), 93 deletions(-) diff --git a/contracts/isolated/src/main/kotlin/contracts/AnotherDummyContract.kt b/contracts/isolated/src/main/kotlin/contracts/AnotherDummyContract.kt index bec6b01cfe..1cee079cbb 100644 --- a/contracts/isolated/src/main/kotlin/contracts/AnotherDummyContract.kt +++ b/contracts/isolated/src/main/kotlin/contracts/AnotherDummyContract.kt @@ -8,6 +8,7 @@ package contracts.isolated +import core.* import core.Contract import core.ContractState import core.TransactionForVerification @@ -15,17 +16,20 @@ import core.crypto.SecureHash // The dummy contract doesn't do anything useful. It exists for testing purposes. -val ANOTHER_DUMMY_PROGRAM_ID = SecureHash.sha256("dummy") +val ANOTHER_DUMMY_PROGRAM_ID = AnotherDummyContract() class AnotherDummyContract : Contract { - class State : ContractState { - override val programRef: SecureHash = ANOTHER_DUMMY_PROGRAM_ID + data class State(val foo: Int) : ContractState { + override val contract = ANOTHER_DUMMY_PROGRAM_ID } override fun verify(tx: TransactionForVerification) { + requireThat { + "justice will be served" by false + } // Always accepts. } // The "empty contract" - override val legalContractReference: SecureHash = SecureHash.sha256("https://anotherdummy.org") + override val legalContractReference = SecureHash.sha256("https://anotherdummy.org") } \ No newline at end of file diff --git a/contracts/src/main/java/contracts/JavaCommercialPaper.java b/contracts/src/main/java/contracts/JavaCommercialPaper.java index 798ff960d2..dd447f0556 100644 --- a/contracts/src/main/java/contracts/JavaCommercialPaper.java +++ b/contracts/src/main/java/contracts/JavaCommercialPaper.java @@ -32,7 +32,8 @@ import static kotlin.collections.CollectionsKt.single; * */ public class JavaCommercialPaper implements Contract { - public static SecureHash JCP_PROGRAM_ID = SecureHash.sha256("java commercial paper (this should be a bytecode hash)"); + //public static SecureHash JCP_PROGRAM_ID = SecureHash.sha256("java commercial paper (this should be a bytecode hash)"); + public static Contract JCP_PROGRAM_ID = new JavaCommercialPaper(); public static class State implements ContractState, ICommercialPaperState { private PartyReference issuance; @@ -87,8 +88,9 @@ public class JavaCommercialPaper implements Contract { @NotNull @Override - public SecureHash getProgramRef() { - return SecureHash.Companion.sha256("java commercial paper (this should be a bytecode hash)"); + public Contract getContract() { + return JCP_PROGRAM_ID; + //return SecureHash.Companion.sha256("java commercial paper (this should be a bytecode hash)"); } @Override diff --git a/contracts/src/main/kotlin/contracts/Cash.kt b/contracts/src/main/kotlin/contracts/Cash.kt index 8901597400..b216bcacc4 100644 --- a/contracts/src/main/kotlin/contracts/Cash.kt +++ b/contracts/src/main/kotlin/contracts/Cash.kt @@ -22,7 +22,8 @@ import java.util.* // // Just a fake program identifier for now. In a real system it could be, for instance, the hash of the program bytecode. -val CASH_PROGRAM_ID = SecureHash.sha256("cash") +val CASH_PROGRAM_ID = Cash() + //SecureHash.sha256("cash") class InsufficientBalanceException(val amountMissing: Amount) : Exception() @@ -62,7 +63,7 @@ class Cash : Contract { /** There must be a MoveCommand signed by this key to claim the amount */ override val owner: PublicKey ) : OwnableState { - override val programRef = CASH_PROGRAM_ID + override val contract = CASH_PROGRAM_ID override fun toString() = "${Emoji.bagOfCash}Cash($amount at $deposit owned by ${owner.toStringShort()})" override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner)) diff --git a/contracts/src/main/kotlin/contracts/CommercialPaper.kt b/contracts/src/main/kotlin/contracts/CommercialPaper.kt index 225fb197a5..417bc5c40e 100644 --- a/contracts/src/main/kotlin/contracts/CommercialPaper.kt +++ b/contracts/src/main/kotlin/contracts/CommercialPaper.kt @@ -38,7 +38,7 @@ import java.time.Instant * to do this in the Apache BVal project). */ -val CP_PROGRAM_ID = SecureHash.sha256("replace-me-later-with-bytecode-hash") +val CP_PROGRAM_ID = CommercialPaper() // TODO: Generalise the notion of an owned instrument into a superclass/supercontract. Consider composition vs inheritance. class CommercialPaper : Contract { @@ -51,7 +51,7 @@ class CommercialPaper : Contract { val faceValue: Amount, val maturityDate: Instant ) : OwnableState, ICommercialPaperState { - override val programRef = CP_PROGRAM_ID + override val contract = CP_PROGRAM_ID fun withoutOwner() = copy(owner = NullPublicKey) override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner)) diff --git a/contracts/src/main/kotlin/contracts/CrowdFund.kt b/contracts/src/main/kotlin/contracts/CrowdFund.kt index 8c7590821e..bc1dc7ce3f 100644 --- a/contracts/src/main/kotlin/contracts/CrowdFund.kt +++ b/contracts/src/main/kotlin/contracts/CrowdFund.kt @@ -15,7 +15,7 @@ import java.security.PublicKey import java.time.Instant import java.util.* -val CROWDFUND_PROGRAM_ID = SecureHash.sha256("crowdsourcing") +val CROWDFUND_PROGRAM_ID = CrowdFund() /** * This is a basic crowd funding contract. It allows a party to create a funding opportunity, then for others to @@ -57,7 +57,7 @@ class CrowdFund : Contract { val closed: Boolean = false, val pledges: List<Pledge> = ArrayList() ) : ContractState { - override val programRef = CROWDFUND_PROGRAM_ID + override val contract = CROWDFUND_PROGRAM_ID val pledgedAmount: Amount get() = pledges.map { it.amount }.sumOrZero(campaign.target.currency) } diff --git a/contracts/src/main/kotlin/contracts/DummyContract.kt b/contracts/src/main/kotlin/contracts/DummyContract.kt index 52956d71c5..5a7761acba 100644 --- a/contracts/src/main/kotlin/contracts/DummyContract.kt +++ b/contracts/src/main/kotlin/contracts/DummyContract.kt @@ -15,11 +15,11 @@ import core.crypto.SecureHash // The dummy contract doesn't do anything useful. It exists for testing purposes. -val DUMMY_PROGRAM_ID = SecureHash.sha256("dummy") +val DUMMY_PROGRAM_ID = DummyContract() class DummyContract : Contract { class State : ContractState { - override val programRef: SecureHash = DUMMY_PROGRAM_ID + override val contract = DUMMY_PROGRAM_ID } override fun verify(tx: TransactionForVerification) { diff --git a/contracts/src/main/kotlin/contracts/IRS.kt b/contracts/src/main/kotlin/contracts/IRS.kt index 273272a927..a8cf5177a8 100644 --- a/contracts/src/main/kotlin/contracts/IRS.kt +++ b/contracts/src/main/kotlin/contracts/IRS.kt @@ -18,7 +18,7 @@ import java.math.RoundingMode import java.time.LocalDate import java.util.* -val IRS_PROGRAM_ID = SecureHash.sha256("replace-me-later-with-bytecode-hash-of-irs-code") +val IRS_PROGRAM_ID = InterestRateSwap() // This is a placeholder for some types that we haven't identified exactly what they are just yet for things still in discussion open class UnknownType() @@ -349,7 +349,7 @@ class InterestRateSwap() : Contract { val calculation: Calculation, val common: Common ) : ContractState { - override val programRef = IRS_PROGRAM_ID + override val contract = IRS_PROGRAM_ID /** * For evaluating arbitrary java on the platform diff --git a/core/src/main/kotlin/core/Structures.kt b/core/src/main/kotlin/core/Structures.kt index 56a8a0d326..08aca588e0 100644 --- a/core/src/main/kotlin/core/Structures.kt +++ b/core/src/main/kotlin/core/Structures.kt @@ -32,11 +32,9 @@ interface NamedByHash { */ interface ContractState { /** - * Refers to a bytecode program that has previously been published to the network. This contract program - * will be executed any time this state is used in an input. It must accept in order for the - * transaction to proceed. + * Contract by which the state belongs */ - val programRef: SecureHash + val contract: Contract } interface OwnableState : ContractState { @@ -144,19 +142,6 @@ interface Contract { val legalContractReference: SecureHash } -/** A contract factory knows how to lazily load and instantiate contract objects. */ -interface ContractFactory { - /** - * Loads, instantiates and returns a contract object from its class bytecodes, given the hash of that bytecode. - * - * @throws UnknownContractException if the hash doesn't map to any known contract. - * @throws ClassCastException if the hash mapped to a contract, but it was not of type T - */ - operator fun <T : Contract> get(hash: SecureHash): T -} - -class UnknownContractException : Exception() - /** * An attachment is a ZIP (or an optionally signed JAR) that contains one or more files. Attachments are meant to * contain public static data which can be referenced from transactions and utilised from contracts. Good examples diff --git a/core/src/main/kotlin/core/TransactionVerification.kt b/core/src/main/kotlin/core/TransactionVerification.kt index 5f24af239d..3e9e2ce89f 100644 --- a/core/src/main/kotlin/core/TransactionVerification.kt +++ b/core/src/main/kotlin/core/TransactionVerification.kt @@ -28,7 +28,7 @@ class TransactionGroup(val transactions: Set<LedgerTransaction>, val nonVerified /** * Verifies the group and returns the set of resolved transactions. */ - fun verify(programMap: ContractFactory): Set<TransactionForVerification> { + fun verify(): Set<TransactionForVerification> { // Check that every input can be resolved to an output. // Check that no output is referenced by more than one input. // Cycles should be impossible due to the use of hashes as pointers. @@ -55,7 +55,7 @@ class TransactionGroup(val transactions: Set<LedgerTransaction>, val nonVerified } for (tx in resolved) - tx.verify(programMap) + tx.verify() return resolved } @@ -79,13 +79,11 @@ data class TransactionForVerification(val inStates: List<ContractState>, * @throws IllegalStateException if a state refers to an unknown contract. */ @Throws(TransactionVerificationException::class, IllegalStateException::class) - fun verify(programMap: ContractFactory) { + fun verify() { // For each input and output state, locate the program to run. Then execute the verification function. If any // throws an exception, the entire transaction is invalid. - val programHashes = (inStates.map { it.programRef } + outStates.map { it.programRef }).toSet() - for (hash in programHashes) { - // TODO: Change this interface to ensure that attachment JARs are put on the classpath before execution. - val program: Contract = programMap[hash] + val programs = (inStates.map { it.contract } + outStates.map { it.contract }).toSet() + for (program in programs) { try { program.verify(this) } catch(e: Throwable) { diff --git a/core/src/main/kotlin/core/serialization/Kryo.kt b/core/src/main/kotlin/core/serialization/Kryo.kt index ffbf602e25..5c05164a3a 100644 --- a/core/src/main/kotlin/core/serialization/Kryo.kt +++ b/core/src/main/kotlin/core/serialization/Kryo.kt @@ -16,8 +16,7 @@ import com.esotericsoftware.kryo.Serializer import com.esotericsoftware.kryo.io.Input import com.esotericsoftware.kryo.io.Output import com.esotericsoftware.kryo.serializers.JavaSerializer -import core.SignedTransaction -import core.WireTransaction +import core.* import core.crypto.SecureHash import core.crypto.generateKeyPair import core.crypto.sha256 @@ -179,6 +178,19 @@ class ImmutableClassSerializer<T : Any>(val klass: KClass<T>) : Serializer<T>() } } +fun Kryo.useClassLoader(cl: ClassLoader, body: () -> Unit) { + val tmp = this.classLoader + this.classLoader = cl + try { + body() + } + finally { + if (tmp != null) { + this.classLoader + } + } +} + fun createKryo(k: Kryo = Kryo()): Kryo { return k.apply { // Allow any class to be deserialized (this is insecure but for prototyping we don't care) @@ -201,6 +213,34 @@ fun createKryo(k: Kryo = Kryo()): Kryo { } }) + register(WireTransaction::class.java, object : Serializer<WireTransaction>() { + override fun write(kryo: Kryo, output: Output, obj: WireTransaction) { + + kryo.writeClassAndObject( output, obj.inputs ) + kryo.writeClassAndObject( output, obj.attachments ) + + kryo.writeClassAndObject( output, obj.outputs ) + kryo.writeClassAndObject( output, obj.commands ) + + } + + override fun read(kryo: Kryo, input: Input, type: Class<WireTransaction>): WireTransaction { + var inputs = kryo.readClassAndObject( input ) as List<StateRef> + var attachments = kryo.readClassAndObject( input ) as List<SecureHash> + + // had we access to AttachmentStorage here, a ClassLoader could be created + + // val customClassLoader = createClassLoader( attachments ) + // kryo.useClassLoader(customClassLoader) { + + var outputs = kryo.readClassAndObject(input) as List<ContractState> + var commands = kryo.readClassAndObject(input) as List<Command> + + return WireTransaction(inputs, attachments, outputs, commands) + // } + } + }) + // Some things where the JRE provides an efficient custom serialisation. val ser = JavaSerializer() val keyPair = generateKeyPair() diff --git a/src/main/kotlin/core/node/AbstractNode.kt b/src/main/kotlin/core/node/AbstractNode.kt index 3e637f8603..a3276337b4 100644 --- a/src/main/kotlin/core/node/AbstractNode.kt +++ b/src/main/kotlin/core/node/AbstractNode.kt @@ -66,22 +66,6 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, val legallyIdentifableAddress: LegallyIdentifiableNode get() = LegallyIdentifiableNode(net.myAddress, storage.myLegalIdentity) - // TODO: This will be obsoleted by "PLT-12: Basic module/sandbox system for contracts" - protected val contractFactory = object : ContractFactory { - private val contracts = mapOf( - CASH_PROGRAM_ID to Cash::class.java, - CP_PROGRAM_ID to CommercialPaper::class.java, - CROWDFUND_PROGRAM_ID to CrowdFund::class.java, - DUMMY_PROGRAM_ID to DummyContract::class.java - ) - - override fun <T : Contract> get(hash: SecureHash): T { - val c = contracts[hash] ?: throw UnknownContractException() - @Suppress("UNCHECKED_CAST") - return c.newInstance() as T - } - } - lateinit var storage: StorageService lateinit var smm: StateMachineManager lateinit var wallet: WalletService @@ -147,12 +131,11 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, val attachments = makeAttachmentStorage(dir) _servicesThatAcceptUploads += attachments val (identity, keypair) = obtainKeyPair(dir) - return constructStorageService(attachments, keypair, identity, contractFactory) + return constructStorageService(attachments, keypair, identity) } - protected open fun constructStorageService(attachments: NodeAttachmentService, keypair: KeyPair, identity: Party, - contractFactory: ContractFactory) = - StorageServiceImpl(attachments, contractFactory, keypair, identity) + protected open fun constructStorageService(attachments: NodeAttachmentService, keypair: KeyPair, identity: Party) = + StorageServiceImpl(attachments, keypair, identity) private fun obtainKeyPair(dir: Path): Pair<Party, KeyPair> { // Load the private identity key, creating it if necessary. The identity key is a long term well known key that diff --git a/src/main/kotlin/core/node/ClassLoader.kt b/src/main/kotlin/core/node/ClassLoader.kt index e57e1360cf..c19b72c29b 100644 --- a/src/main/kotlin/core/node/ClassLoader.kt +++ b/src/main/kotlin/core/node/ClassLoader.kt @@ -6,6 +6,8 @@ import java.io.File import java.io.FileOutputStream import java.net.URL import java.net.URLClassLoader +import java.security.AccessControlContext +import java.security.ProtectionDomain import java.util.* import java.util.jar.JarEntry @@ -28,6 +30,10 @@ class ClassLoader private constructor(val tmpFiles: List<File> ) } } + override fun loadClass(name: String?, resolve: Boolean): Class<*>? { + return super.loadClass(name, resolve) + } + companion object { fun create(streams: List<Attachment>) : ClassLoader { diff --git a/src/main/kotlin/core/node/services/Services.kt b/src/main/kotlin/core/node/services/Services.kt index 6974af1c4e..538369c80a 100644 --- a/src/main/kotlin/core/node/services/Services.kt +++ b/src/main/kotlin/core/node/services/Services.kt @@ -116,11 +116,6 @@ interface StorageService { /** Provides access to storage of arbitrary JAR files (which may contain only data, no code). */ val attachments: AttachmentStorage - /** - * A map of program hash->contract class type, used for verification. - */ - val contractPrograms: ContractFactory - /** * Returns the legal identity that this node is configured with. Assumed to be initialised when the node is * first installed. @@ -186,6 +181,6 @@ interface ServiceHub { storageService.validatedTransactions[it.txhash] ?: throw TransactionResolutionException(it.txhash) } val ltxns = dependencies.map { it.verifyToLedgerTransaction(identityService, storageService.attachments) } - TransactionGroup(setOf(ltx), ltxns.toSet()).verify(storageService.contractPrograms) + TransactionGroup(setOf(ltx), ltxns.toSet()).verify() } } diff --git a/src/main/kotlin/core/node/services/StorageServiceImpl.kt b/src/main/kotlin/core/node/services/StorageServiceImpl.kt index b0a0490282..3d7d07c6ff 100644 --- a/src/main/kotlin/core/node/services/StorageServiceImpl.kt +++ b/src/main/kotlin/core/node/services/StorageServiceImpl.kt @@ -1,6 +1,5 @@ package core.node.services -import core.ContractFactory import core.Party import core.SignedTransaction import core.crypto.SecureHash @@ -10,7 +9,6 @@ import java.security.KeyPair import java.util.* open class StorageServiceImpl(attachments: AttachmentStorage, - contractFactory: ContractFactory, keypair: KeyPair, identity: Party = Party("Unit test party", keypair.public), // This parameter is for unit tests that want to observe operation details. @@ -39,7 +37,6 @@ open class StorageServiceImpl(attachments: AttachmentStorage, get() = getMapOriginal("state-machines") override val attachments: AttachmentStorage = attachments - override val contractPrograms = contractFactory override val myLegalIdentity = identity override val myLegalIdentityKey = keypair } \ No newline at end of file diff --git a/src/main/kotlin/protocols/ResolveTransactionsProtocol.kt b/src/main/kotlin/protocols/ResolveTransactionsProtocol.kt index 8e6a638c9d..a224b3b0d4 100644 --- a/src/main/kotlin/protocols/ResolveTransactionsProtocol.kt +++ b/src/main/kotlin/protocols/ResolveTransactionsProtocol.kt @@ -66,7 +66,7 @@ class ResolveTransactionsProtocol(private val txHashes: Set<SecureHash>, } // Run all the contracts and throw an exception if any of them reject. - TransactionGroup(toVerify, alreadyVerified).verify(serviceHub.storageService.contractPrograms) + TransactionGroup(toVerify, alreadyVerified).verify() // Now write all the transactions we just validated back to the database for next time, including // signatures so we can serve up these transactions to other peers when we, in turn, send one that diff --git a/src/test/kotlin/contracts/CommercialPaperTests.kt b/src/test/kotlin/contracts/CommercialPaperTests.kt index b252f24e38..0c85c5c466 100644 --- a/src/test/kotlin/contracts/CommercialPaperTests.kt +++ b/src/test/kotlin/contracts/CommercialPaperTests.kt @@ -219,11 +219,11 @@ class CommercialPaperTestsGeneric { val validRedemption = makeRedeemTX(TEST_TX_TIME + 31.days) val e = assertFailsWith(TransactionVerificationException::class) { - TransactionGroup(setOf(issueTX, moveTX, tooEarlyRedemption), setOf(corpWalletTX, alicesWalletTX)).verify(MockContractFactory) + TransactionGroup(setOf(issueTX, moveTX, tooEarlyRedemption), setOf(corpWalletTX, alicesWalletTX)).verify() } assertTrue(e.cause!!.message!!.contains("paper must have matured")) - TransactionGroup(setOf(issueTX, moveTX, validRedemption), setOf(corpWalletTX, alicesWalletTX)).verify(MockContractFactory) + TransactionGroup(setOf(issueTX, moveTX, validRedemption), setOf(corpWalletTX, alicesWalletTX)).verify() } // Generate a trade lifecycle with various parameters. diff --git a/src/test/kotlin/contracts/CrowdFundTests.kt b/src/test/kotlin/contracts/CrowdFundTests.kt index e7dd5ed531..e734ae73a3 100644 --- a/src/test/kotlin/contracts/CrowdFundTests.kt +++ b/src/test/kotlin/contracts/CrowdFundTests.kt @@ -160,11 +160,11 @@ class CrowdFundTests { val validClose = makeFundedTX(TEST_TX_TIME + 8.days) val e = assertFailsWith(TransactionVerificationException::class) { - TransactionGroup(setOf(registerTX, pledgeTX, tooEarlyClose), setOf(miniCorpWalletTx, aliceWalletTX)).verify(MockContractFactory) + TransactionGroup(setOf(registerTX, pledgeTX, tooEarlyClose), setOf(miniCorpWalletTx, aliceWalletTX)).verify() } assertTrue(e.cause!!.message!!.contains("the closing date has past")) // This verification passes - TransactionGroup(setOf(registerTX, pledgeTX, validClose), setOf(aliceWalletTX)).verify(MockContractFactory) + TransactionGroup(setOf(registerTX, pledgeTX, validClose), setOf(aliceWalletTX)).verify() } } \ No newline at end of file diff --git a/src/test/kotlin/core/MockServices.kt b/src/test/kotlin/core/MockServices.kt index 43f0f500aa..bace9ab1be 100644 --- a/src/test/kotlin/core/MockServices.kt +++ b/src/test/kotlin/core/MockServices.kt @@ -116,15 +116,7 @@ class MockAttachmentStorage : AttachmentStorage { } @ThreadSafe -class MockStorageService : StorageServiceImpl(MockAttachmentStorage(), MockContractFactory, generateKeyPair()) { -} - -object MockContractFactory : ContractFactory { - override operator fun <T : Contract> get(hash: SecureHash): T { - val clazz = TEST_PROGRAM_MAP[hash] ?: throw UnknownContractException() - @Suppress("UNCHECKED_CAST") - return clazz.newInstance() as T - } +class MockStorageService : StorageServiceImpl(MockAttachmentStorage(), generateKeyPair()) { } class MockServices( diff --git a/src/test/kotlin/core/TransactionGroupTests.kt b/src/test/kotlin/core/TransactionGroupTests.kt index 81746777eb..730e9873ea 100644 --- a/src/test/kotlin/core/TransactionGroupTests.kt +++ b/src/test/kotlin/core/TransactionGroupTests.kt @@ -153,6 +153,6 @@ class TransactionGroupTests { // Now go through the conversion -> verification path with them. val ltxns = signedTxns.map { it.verifyToLedgerTransaction(MockIdentityService, MockStorageService().attachments) }.toSet() - TransactionGroup(ltxns, emptySet()).verify(MockContractFactory) + TransactionGroup(ltxns, emptySet()).verify() } } \ No newline at end of file diff --git a/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt b/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt index cba57e831d..955cefc1de 100644 --- a/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt +++ b/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt @@ -195,10 +195,9 @@ class TwoPartyTradeProtocolTests : TestWithInMemoryNetwork() { return net.createNode(null) { path, config, net, tsNode -> object : MockNetwork.MockNode(path, config, net, tsNode) { // That constructs the storage service object in a customised way ... - override fun constructStorageService(attachments: NodeAttachmentService, keypair: KeyPair, identity: Party, - contractFactory: ContractFactory): StorageServiceImpl { + override fun constructStorageService(attachments: NodeAttachmentService, keypair: KeyPair, identity: Party): StorageServiceImpl { // To use RecordingMaps instead of ordinary HashMaps. - return StorageServiceImpl(attachments, contractFactory, keypair, identity, { tableName -> name }) + return StorageServiceImpl(attachments, keypair, identity, { tableName -> name }) } } } diff --git a/src/test/kotlin/core/node/ClassLoaderTests.kt b/src/test/kotlin/core/node/ClassLoaderTests.kt index 1c10317dc3..c09acc2e11 100644 --- a/src/test/kotlin/core/node/ClassLoaderTests.kt +++ b/src/test/kotlin/core/node/ClassLoaderTests.kt @@ -173,4 +173,9 @@ class ClassLoaderTests { assertNotNull(state2) } + @Test + fun `white list serialization`() { + + } + } \ No newline at end of file diff --git a/src/test/kotlin/core/testutils/TestUtils.kt b/src/test/kotlin/core/testutils/TestUtils.kt index 68aac26d83..d2d67402be 100644 --- a/src/test/kotlin/core/testutils/TestUtils.kt +++ b/src/test/kotlin/core/testutils/TestUtils.kt @@ -74,7 +74,7 @@ val TEST_KEYS_TO_CORP_MAP: Map<PublicKey, Party> = mapOf( // In a real system this would be a persistent map of hash to bytecode and we'd instantiate the object as needed inside // a sandbox. For unit tests we just have a hard-coded list. -val TEST_PROGRAM_MAP: Map<SecureHash, Class<out Contract>> = mapOf( +val TEST_PROGRAM_MAP: Map<Contract, Class<out Contract>> = mapOf( CASH_PROGRAM_ID to Cash::class.java, CP_PROGRAM_ID to CommercialPaper::class.java, JavaCommercialPaper.JCP_PROGRAM_ID to JavaCommercialPaper::class.java, @@ -162,7 +162,7 @@ open class TransactionForTest : AbstractTransactionForTest() { protected fun run(time: Instant) { val cmds = commandsToAuthenticatedObjects() val tx = TransactionForVerification(inStates, outStates.map { it.state }, emptyList(), cmds, SecureHash.randomSHA256()) - tx.verify(MockContractFactory) + tx.verify() } fun accepts(time: Instant = TEST_TX_TIME) = run(time) @@ -319,7 +319,7 @@ class TransactionGroupDSL<T : ContractState>(private val stateType: Class<T>) { fun verify() { val group = toTransactionGroup() try { - group.verify(MockContractFactory) + group.verify() } catch (e: TransactionVerificationException) { // Let the developer know the index of the transaction that failed. val wtx: WireTransaction = txns.find { it.id == e.tx.origHash }!!