diff --git a/.gitignore b/.gitignore index 0672057c36..ba6dd8df33 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ tags .gradle local.properties -/docs/build/doctrees # General build files **/build/* @@ -34,7 +33,6 @@ lib/dokka.jar .idea/libraries .idea/shelf .idea/dataSources -.idea/modules.xml # if you remove the above rule, at least ignore the following: diff --git a/core/src/main/kotlin/net/corda/core/contracts/TransactionTypes.kt b/core/src/main/kotlin/net/corda/core/contracts/TransactionTypes.kt index 3570bc35e1..7cd6ef4d39 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/TransactionTypes.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/TransactionTypes.kt @@ -17,6 +17,7 @@ sealed class TransactionType { * * Note: Presence of _signatures_ is not checked, only the public keys to be signed for. */ + @Throws(TransactionVerificationException::class) fun verify(tx: LedgerTransaction) { require(tx.notary != null || tx.timestamp == null) { "Transactions with timestamps must be notarised." } val duplicates = detectDuplicateInputs(tx) diff --git a/core/src/main/kotlin/net/corda/core/contracts/TransactionVerification.kt b/core/src/main/kotlin/net/corda/core/contracts/TransactionVerification.kt index 060d8c49f5..2c59c872f9 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/TransactionVerification.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/TransactionVerification.kt @@ -3,6 +3,7 @@ package net.corda.core.contracts import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.Party import net.corda.core.crypto.SecureHash +import net.corda.core.flows.FlowException import net.corda.core.transactions.LedgerTransaction import java.util.* @@ -85,30 +86,35 @@ data class TransactionForContract(val inputs: List, data class InOutGroup(val inputs: List, val outputs: List, val groupingKey: K) } -class TransactionResolutionException(val hash: SecureHash) : Exception() { - override fun toString() = "Transaction resolution failure for $hash" +class TransactionResolutionException(val hash: SecureHash) : FlowException() { + override fun toString(): String = "Transaction resolution failure for $hash" +} + +class AttachmentResolutionException(val hash : SecureHash) : FlowException() { + override fun toString(): String = "Attachment resolution failure for $hash" } class TransactionConflictException(val conflictRef: StateRef, val tx1: LedgerTransaction, val tx2: LedgerTransaction) : Exception() -sealed class TransactionVerificationException(val tx: LedgerTransaction, cause: Throwable?) : Exception(cause) { +sealed class TransactionVerificationException(val tx: LedgerTransaction, cause: Throwable?) : FlowException(cause) { class ContractRejection(tx: LedgerTransaction, val contract: Contract, cause: Throwable?) : TransactionVerificationException(tx, cause) class MoreThanOneNotary(tx: LedgerTransaction) : TransactionVerificationException(tx, null) class SignersMissing(tx: LedgerTransaction, val missing: List) : TransactionVerificationException(tx, null) { - override fun toString() = "Signers missing: ${missing.joinToString()}" + override fun toString(): String = "Signers missing: ${missing.joinToString()}" } class DuplicateInputStates(tx: LedgerTransaction, val duplicates: Set) : TransactionVerificationException(tx, null) { - override fun toString() = "Duplicate inputs: ${duplicates.joinToString()}" + override fun toString(): String = "Duplicate inputs: ${duplicates.joinToString()}" } class InvalidNotaryChange(tx: LedgerTransaction) : TransactionVerificationException(tx, null) class NotaryChangeInWrongTransactionType(tx: LedgerTransaction, val outputNotary: Party) : TransactionVerificationException(tx, null) { - override fun toString(): String = "Found unexpected notary change in transaction. Tx notary: ${tx.notary}, found: ${outputNotary}" + override fun toString(): String { + return "Found unexpected notary change in transaction. Tx notary: ${tx.notary}, found: $outputNotary" + } } class TransactionMissingEncumbranceException(tx: LedgerTransaction, val missing: Int, val inOut: Direction) : TransactionVerificationException(tx, null) { - override val message: String? - get() = "Missing required encumbrance ${missing} in ${inOut}" + override val message: String get() = "Missing required encumbrance $missing in $inOut" } enum class Direction { INPUT, diff --git a/core/src/main/kotlin/net/corda/core/flows/FlowException.kt b/core/src/main/kotlin/net/corda/core/flows/FlowException.kt index fc8014f4d4..9419049d68 100644 --- a/core/src/main/kotlin/net/corda/core/flows/FlowException.kt +++ b/core/src/main/kotlin/net/corda/core/flows/FlowException.kt @@ -9,5 +9,8 @@ package net.corda.core.flows * [FlowException] (or a subclass) can be a valid expected response from a flow, particularly ones which act as a service. * It is recommended a [FlowLogic] document the [FlowException] types it can throw. */ -open class FlowException @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) - : Exception(message, cause) +open class FlowException(override val message: String?, override val cause: Throwable?) : Exception() { + constructor(message: String?) : this(message, null) + constructor(cause: Throwable?) : this(cause?.toString(), cause) + constructor() : this(null, null) +} diff --git a/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt index 26c44f711f..4a548c0c46 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt @@ -54,6 +54,7 @@ class LedgerTransaction( * * @throws TransactionVerificationException if anything goes wrong. */ + @Throws(TransactionVerificationException::class) fun verify() = type.verify(this) // TODO: When we upgrade to Kotlin 1.1 we can make this a data class again and have the compiler generate these. diff --git a/core/src/main/kotlin/net/corda/core/transactions/SignedTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/SignedTransaction.kt index efde6949fd..49349f0882 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/SignedTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/SignedTransaction.kt @@ -1,5 +1,6 @@ package net.corda.core.transactions +import net.corda.core.contracts.AttachmentResolutionException import net.corda.core.contracts.NamedByHash import net.corda.core.contracts.TransactionResolutionException import net.corda.core.crypto.CompositeKey @@ -8,7 +9,6 @@ import net.corda.core.crypto.SecureHash import net.corda.core.crypto.signWithECDSA import net.corda.core.node.ServiceHub import net.corda.core.serialization.SerializedBytes -import java.io.FileNotFoundException import java.security.KeyPair import java.security.SignatureException import java.util.* @@ -127,12 +127,12 @@ data class SignedTransaction(val txBits: SerializedBytes, * [WireTransaction.toLedgerTransaction] with the passed in [ServiceHub] to resolve the dependencies, * returning an unverified LedgerTransaction. * - * @throws FileNotFoundException if a required attachment was not found in storage. + * @throws AttachmentResolutionException if a required attachment was not found in storage. * @throws TransactionResolutionException if an input points to a transaction not found in storage. * @throws SignatureException if any signatures were invalid or unrecognised * @throws SignaturesMissingException if any signatures that should have been present are missing. */ - @Throws(FileNotFoundException::class, TransactionResolutionException::class, SignaturesMissingException::class) + @Throws(AttachmentResolutionException::class, TransactionResolutionException::class, SignatureException::class) fun toLedgerTransaction(services: ServiceHub) = verifySignatures().toLedgerTransaction(services) /** diff --git a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt index 1a8a40ab04..583448f518 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt @@ -12,7 +12,6 @@ import net.corda.core.serialization.THREAD_LOCAL_KRYO import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize import net.corda.core.utilities.Emoji -import java.io.FileNotFoundException import java.security.PublicKey /** @@ -66,10 +65,10 @@ class WireTransaction( * Looks up identities and attachments from storage to generate a [LedgerTransaction]. A transaction is expected to * have been fully resolved using the resolution flow by this point. * - * @throws FileNotFoundException if a required attachment was not found in storage. + * @throws AttachmentResolutionException if a required attachment was not found in storage. * @throws TransactionResolutionException if an input points to a transaction not found in storage. */ - @Throws(FileNotFoundException::class, TransactionResolutionException::class) + @Throws(AttachmentResolutionException::class, TransactionResolutionException::class) fun toLedgerTransaction(services: ServiceHub): LedgerTransaction { // Look up public keys to authenticated identities. This is just a stub placeholder and will all change in future. val authenticatedArgs = commands.map { @@ -78,7 +77,7 @@ class WireTransaction( } // Open attachments specified in this transaction. If we haven't downloaded them, we fail. val attachments = attachments.map { - services.storageService.attachments.openAttachment(it) ?: throw FileNotFoundException(it.toString()) + services.storageService.attachments.openAttachment(it) ?: throw AttachmentResolutionException(it) } val resolvedInputs = inputs.map { StateAndRef(services.loadState(it), it) } return LedgerTransaction(resolvedInputs, outputs, authenticatedArgs, attachments, id, notary, mustSign, timestamp, type) diff --git a/core/src/main/kotlin/net/corda/core/utilities/UntrustworthyData.kt b/core/src/main/kotlin/net/corda/core/utilities/UntrustworthyData.kt index b220ea20ca..7db3d496df 100644 --- a/core/src/main/kotlin/net/corda/core/utilities/UntrustworthyData.kt +++ b/core/src/main/kotlin/net/corda/core/utilities/UntrustworthyData.kt @@ -18,11 +18,18 @@ class UntrustworthyData(private val fromUntrustedWorld: T) { @Deprecated("Accessing the untrustworthy data directly without validating it first is a bad idea") get() = fromUntrustedWorld - @Suppress("DEPRECATION") @Throws(FlowException::class) - inline fun unwrap(validator: (T) -> R) = validator(data) + fun unwrap(validator: Validator) = validator.validate(fromUntrustedWorld) @Suppress("DEPRECATION") @Deprecated("This old name was confusing, use unwrap instead", replaceWith = ReplaceWith("unwrap")) inline fun validate(validator: (T) -> R) = validator(data) + + interface Validator { + @Throws(FlowException::class) + fun validate(data: T): R + } } + +@Suppress("DEPRECATION") +inline fun UntrustworthyData.unwrap(validator: (T) -> R): R = validator(data) diff --git a/core/src/main/kotlin/net/corda/flows/AbstractStateReplacementFlow.kt b/core/src/main/kotlin/net/corda/flows/AbstractStateReplacementFlow.kt index a05f15dd1f..8d5e520b44 100644 --- a/core/src/main/kotlin/net/corda/flows/AbstractStateReplacementFlow.kt +++ b/core/src/main/kotlin/net/corda/flows/AbstractStateReplacementFlow.kt @@ -15,6 +15,7 @@ import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.WireTransaction import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.UntrustworthyData +import net.corda.core.utilities.unwrap import net.corda.flows.AbstractStateReplacementFlow.Acceptor import net.corda.flows.AbstractStateReplacementFlow.Instigator diff --git a/core/src/main/kotlin/net/corda/flows/FetchDataFlow.kt b/core/src/main/kotlin/net/corda/flows/FetchDataFlow.kt index 0be2b1a081..1661476aae 100644 --- a/core/src/main/kotlin/net/corda/flows/FetchDataFlow.kt +++ b/core/src/main/kotlin/net/corda/flows/FetchDataFlow.kt @@ -7,6 +7,7 @@ import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowException import net.corda.core.flows.FlowLogic import net.corda.core.utilities.UntrustworthyData +import net.corda.core.utilities.unwrap import net.corda.flows.FetchDataFlow.DownloadedVsRequestedDataMismatch import net.corda.flows.FetchDataFlow.HashNotFound import java.util.* diff --git a/core/src/main/kotlin/net/corda/flows/NotaryFlow.kt b/core/src/main/kotlin/net/corda/flows/NotaryFlow.kt index f29281fc7c..66ee378e51 100644 --- a/core/src/main/kotlin/net/corda/flows/NotaryFlow.kt +++ b/core/src/main/kotlin/net/corda/flows/NotaryFlow.kt @@ -5,8 +5,8 @@ import net.corda.core.crypto.DigitalSignature import net.corda.core.crypto.Party import net.corda.core.crypto.SignedData import net.corda.core.crypto.signWithECDSA -import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowException +import net.corda.core.flows.FlowLogic import net.corda.core.node.services.TimestampChecker import net.corda.core.node.services.UniquenessException import net.corda.core.node.services.UniquenessProvider @@ -14,6 +14,7 @@ import net.corda.core.serialization.serialize import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.WireTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.unwrap object NotaryFlow { /** diff --git a/core/src/main/kotlin/net/corda/flows/TwoPartyDealFlow.kt b/core/src/main/kotlin/net/corda/flows/TwoPartyDealFlow.kt index f8ae8c5905..6e3556d85d 100644 --- a/core/src/main/kotlin/net/corda/flows/TwoPartyDealFlow.kt +++ b/core/src/main/kotlin/net/corda/flows/TwoPartyDealFlow.kt @@ -16,6 +16,7 @@ import net.corda.core.transactions.WireTransaction import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.UntrustworthyData import net.corda.core.utilities.trace +import net.corda.core.utilities.unwrap import java.security.KeyPair /** diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt index 02f25559eb..cf07bc3faf 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt @@ -14,6 +14,7 @@ import net.corda.core.flows.FlowLogic import net.corda.core.node.PluginServiceHub import net.corda.core.node.ServiceHub import net.corda.core.transactions.SignedTransaction +import net.corda.core.utilities.unwrap import net.corda.flows.FinalityFlow import net.corda.flows.ResolveTransactionsFlow import java.util.* diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt index 0818835fa1..099dc63b72 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt @@ -8,6 +8,7 @@ import net.corda.core.node.PluginServiceHub import net.corda.core.node.ServiceHub import net.corda.core.node.services.linearHeadsOfType import net.corda.core.transactions.SignedTransaction +import net.corda.core.utilities.unwrap import net.corda.flows.FinalityFlow import java.security.PublicKey import java.time.Duration diff --git a/finance/src/main/kotlin/net/corda/flows/IssuerFlow.kt b/finance/src/main/kotlin/net/corda/flows/IssuerFlow.kt index ff946f0fa4..921a6120eb 100644 --- a/finance/src/main/kotlin/net/corda/flows/IssuerFlow.kt +++ b/finance/src/main/kotlin/net/corda/flows/IssuerFlow.kt @@ -9,6 +9,7 @@ import net.corda.core.node.PluginServiceHub import net.corda.core.serialization.OpaqueBytes import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.unwrap import java.util.* /** diff --git a/finance/src/main/kotlin/net/corda/flows/TwoPartyTradeFlow.kt b/finance/src/main/kotlin/net/corda/flows/TwoPartyTradeFlow.kt index aadd430fe3..c1cfade1cf 100644 --- a/finance/src/main/kotlin/net/corda/flows/TwoPartyTradeFlow.kt +++ b/finance/src/main/kotlin/net/corda/flows/TwoPartyTradeFlow.kt @@ -13,6 +13,7 @@ import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.WireTransaction import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.trace +import net.corda.core.utilities.unwrap import java.security.KeyPair import java.util.* diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt index 1a1018db51..c0df706bcc 100644 --- a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt +++ b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt @@ -10,6 +10,7 @@ import net.corda.core.getOrThrow import net.corda.core.messaging.CordaRPCOps import net.corda.core.random63BitValue import net.corda.core.seconds +import net.corda.core.utilities.unwrap import net.corda.node.internal.Node import net.corda.node.services.User import net.corda.node.services.config.SSLConfiguration diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/DataVendingService.kt b/node/src/main/kotlin/net/corda/node/services/persistence/DataVendingService.kt index d43fad7564..2b4dddeb5d 100644 --- a/node/src/main/kotlin/net/corda/node/services/persistence/DataVendingService.kt +++ b/node/src/main/kotlin/net/corda/node/services/persistence/DataVendingService.kt @@ -10,6 +10,7 @@ import net.corda.core.node.PluginServiceHub import net.corda.core.node.recordTransactions import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.transactions.SignedTransaction +import net.corda.core.utilities.unwrap import net.corda.flows.* import java.util.function.Function import javax.annotation.concurrent.ThreadSafe diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/StateMachineManagerTests.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/StateMachineManagerTests.kt index b0ed7a81da..ce06994a5d 100644 --- a/node/src/test/kotlin/net/corda/node/services/statemachine/StateMachineManagerTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/statemachine/StateMachineManagerTests.kt @@ -21,6 +21,7 @@ import net.corda.core.random63BitValue import net.corda.core.rootCause import net.corda.core.serialization.OpaqueBytes import net.corda.core.serialization.deserialize +import net.corda.core.utilities.unwrap import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder import net.corda.flows.CashCommand diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt index b524dedf9b..aedf23af3f 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt @@ -14,6 +14,7 @@ import net.corda.core.node.services.ServiceType import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.transactions.FilteredTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.unwrap import net.corda.irs.flows.FixingFlow import net.corda.irs.flows.RatesFixFlow import net.corda.node.services.api.AcceptsFileUpload diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/ExitServerFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/ExitServerFlow.kt index 044036d19c..7b88cd12e2 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/ExitServerFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/ExitServerFlow.kt @@ -7,6 +7,7 @@ import net.corda.core.flows.FlowLogic import net.corda.core.node.CordaPluginRegistry import net.corda.core.node.NodeInfo import net.corda.core.node.PluginServiceHub +import net.corda.core.utilities.unwrap import net.corda.testing.node.MockNetworkMapCache import java.util.concurrent.TimeUnit import java.util.function.Function diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/RatesFixFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/RatesFixFlow.kt index 2bf9be5e1e..917cc2b9f1 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/RatesFixFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/RatesFixFlow.kt @@ -10,6 +10,7 @@ import net.corda.core.flows.FlowLogic import net.corda.core.transactions.FilteredTransaction import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.unwrap import net.corda.irs.flows.RatesFixFlow.FixOutOfRange import net.corda.irs.utilities.suggestInterestRateAnnouncementTimeWindow import java.math.BigDecimal diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt index d6918d9020..7f0d725f87 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt @@ -7,6 +7,7 @@ import net.corda.core.node.CordaPluginRegistry import net.corda.core.node.NodeInfo import net.corda.core.node.PluginServiceHub import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.unwrap import net.corda.node.utilities.TestClock import net.corda.testing.node.MockNetworkMapCache import java.time.LocalDate diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt index c9e60d7296..822c104c23 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt @@ -5,6 +5,7 @@ import net.corda.core.crypto.Party import net.corda.core.flows.FlowLogic import net.corda.core.node.PluginServiceHub import net.corda.core.transactions.SignedTransaction +import net.corda.core.utilities.unwrap import net.corda.flows.TwoPartyDealFlow import net.corda.vega.contracts.IRSState import net.corda.vega.contracts.OGTrade diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt index 40ba74a159..6617862b7c 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt @@ -18,6 +18,7 @@ import net.corda.core.messaging.Ack import net.corda.core.node.PluginServiceHub import net.corda.core.node.services.dealsWith import net.corda.core.transactions.SignedTransaction +import net.corda.core.utilities.unwrap import net.corda.flows.AbstractStateReplacementFlow.Proposal import net.corda.flows.StateReplacementException import net.corda.flows.TwoPartyDealFlow diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt index 1226e178b9..35382d9ba1 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt @@ -12,6 +12,7 @@ import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.Emoji import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.unwrap import net.corda.flows.TwoPartyTradeFlow import net.corda.node.services.persistence.NodeAttachmentService import java.nio.file.Path