diff --git a/core/src/main/kotlin/net/corda/core/contracts/Amount.kt b/core/src/main/kotlin/net/corda/core/contracts/Amount.kt index e8d3982c2f..e08ddce671 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/Amount.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/Amount.kt @@ -391,10 +391,10 @@ class AmountTransfer(val quantityDelta: Long, * relative asset exchange happens, but with each party exchanging versus a central counterparty, or clearing house. * * @param centralParty The central party to face the exchange against. - * @return Returns two new AmountTransfers each between one of the original parties and the centralParty. + * @return Returns a list of two new AmountTransfers each between one of the original parties and the centralParty. * The net total exchange is the same as in the original input. */ - fun novate(centralParty: P): Pair, AmountTransfer> = Pair(copy(destination = centralParty), copy(source = centralParty)) + fun novate(centralParty: P): List> = listOf(copy(destination = centralParty), copy(source = centralParty)) /** * Applies this AmountTransfer to a list of [SourceAndAmount] objects representing balances. diff --git a/core/src/main/kotlin/net/corda/core/contracts/Structures.kt b/core/src/main/kotlin/net/corda/core/contracts/Structures.kt index 437de33344..370e3bd06a 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/Structures.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/Structures.kt @@ -147,6 +147,12 @@ data class Issued(val issuer: PartyAndReference, val product: P) { fun Amount>.withoutIssuer(): Amount = Amount(quantity, token.product) // DOCSTART 3 + +/** + * Return structure for [OwnableState.withNewOwner] + */ +data class CommandAndState(val command: CommandData, val ownableState: OwnableState) + /** * A contract state that can have a single owner. */ @@ -155,7 +161,7 @@ interface OwnableState : ContractState { val owner: AbstractParty /** Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone */ - fun withNewOwner(newOwner: AbstractParty): Pair + fun withNewOwner(newOwner: AbstractParty): CommandAndState } // DOCEND 3 diff --git a/core/src/main/kotlin/net/corda/core/node/PhysicalLocationStructures.kt b/core/src/main/kotlin/net/corda/core/node/PhysicalLocationStructures.kt index 049845432f..754fbbc44e 100644 --- a/core/src/main/kotlin/net/corda/core/node/PhysicalLocationStructures.kt +++ b/core/src/main/kotlin/net/corda/core/node/PhysicalLocationStructures.kt @@ -3,6 +3,8 @@ package net.corda.core.node import net.corda.core.serialization.CordaSerializable import java.util.* +data class ScreenCoordinate(val screenX: Double, val screenY: Double) + /** A latitude/longitude pair. */ @CordaSerializable data class WorldCoordinate(val latitude: Double, val longitude: Double) { @@ -21,7 +23,7 @@ data class WorldCoordinate(val latitude: Double, val longitude: Double) { */ @Suppress("unused") // Used from the visualiser GUI. fun project(screenWidth: Double, screenHeight: Double, topLatitude: Double, bottomLatitude: Double, - leftLongitude: Double, rightLongitude: Double): Pair { + leftLongitude: Double, rightLongitude: Double): ScreenCoordinate { require(latitude in bottomLatitude..topLatitude) require(longitude in leftLongitude..rightLongitude) @@ -33,7 +35,7 @@ data class WorldCoordinate(val latitude: Double, val longitude: Double) { val topLatRel = screenYRelative(topLatitude) val bottomLatRel = screenYRelative(bottomLatitude) fun latitudeToScreenY(lat: Double) = screenHeight * (screenYRelative(lat) - topLatRel) / (bottomLatRel - topLatRel) - return Pair(longitudeToScreenX(longitude), latitudeToScreenY(latitude)) + return ScreenCoordinate(longitudeToScreenX(longitude), latitudeToScreenY(latitude)) } } diff --git a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt index 9f21d4d944..bc05d5be77 100644 --- a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt +++ b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt @@ -202,7 +202,7 @@ class ContractUpgradeFlowTest { override fun move(newAmount: Amount>, newOwner: AbstractParty) = copy(amount = amount.copy(newAmount.quantity), owners = listOf(newOwner)) override fun toString() = "${Emoji.bagOfCash}New Cash($amount at ${amount.token.issuer} owned by $owner)" - override fun withNewOwner(newOwner: AbstractParty) = Pair(Cash.Commands.Move(), copy(owners = listOf(newOwner))) + override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(Cash.Commands.Move(), copy(owners = listOf(newOwner))) } override fun upgrade(state: Cash.State) = CashV2.State(state.amount.times(1000), listOf(state.owner)) diff --git a/core/src/test/kotlin/net/corda/core/serialization/TransactionSerializationTests.kt b/core/src/test/kotlin/net/corda/core/serialization/TransactionSerializationTests.kt index 88e2eecfc2..492b50826f 100644 --- a/core/src/test/kotlin/net/corda/core/serialization/TransactionSerializationTests.kt +++ b/core/src/test/kotlin/net/corda/core/serialization/TransactionSerializationTests.kt @@ -32,7 +32,7 @@ class TransactionSerializationTests : TestDependencyInjectionBase() { override val participants: List get() = listOf(owner) - override fun withNewOwner(newOwner: AbstractParty) = Pair(Commands.Move(), copy(owner = newOwner)) + override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(Commands.Move(), copy(owner = newOwner)) } interface Commands : CommandData { diff --git a/finance/src/main/java/net/corda/contracts/JavaCommercialPaper.java b/finance/src/main/java/net/corda/contracts/JavaCommercialPaper.java index 3472b8bd2c..e51d3889fe 100644 --- a/finance/src/main/java/net/corda/contracts/JavaCommercialPaper.java +++ b/finance/src/main/java/net/corda/contracts/JavaCommercialPaper.java @@ -68,8 +68,8 @@ public class JavaCommercialPaper implements Contract { @NotNull @Override - public Pair withNewOwner(@NotNull AbstractParty newOwner) { - return new Pair<>(new Commands.Move(), new State(this.issuance, newOwner, this.faceValue, this.maturityDate)); + public CommandAndState withNewOwner(@NotNull AbstractParty newOwner) { + return new CommandAndState(new Commands.Move(), new State(this.issuance, newOwner, this.faceValue, this.maturityDate)); } public ICommercialPaperState withFaceValue(Amount> newFaceValue) { diff --git a/finance/src/main/kotlin/net/corda/contracts/CommercialPaper.kt b/finance/src/main/kotlin/net/corda/contracts/CommercialPaper.kt index 70b795a934..eb22a8a58f 100644 --- a/finance/src/main/kotlin/net/corda/contracts/CommercialPaper.kt +++ b/finance/src/main/kotlin/net/corda/contracts/CommercialPaper.kt @@ -73,7 +73,7 @@ class CommercialPaper : Contract { val token: Issued get() = Issued(issuance, Terms(faceValue.token, maturityDate)) - override fun withNewOwner(newOwner: AbstractParty) = Pair(Commands.Move(), copy(owner = newOwner)) + override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(Commands.Move(), copy(owner = newOwner)) override fun toString() = "${Emoji.newspaper}CommercialPaper(of $faceValue redeemable on $maturityDate by '$issuance', owned by $owner)" // Although kotlin is smart enough not to need these, as we are using the ICommercialPaperState, we need to declare them explicitly for use later, diff --git a/finance/src/main/kotlin/net/corda/contracts/CommercialPaperLegacy.kt b/finance/src/main/kotlin/net/corda/contracts/CommercialPaperLegacy.kt index b53246d25b..b7086a6a29 100644 --- a/finance/src/main/kotlin/net/corda/contracts/CommercialPaperLegacy.kt +++ b/finance/src/main/kotlin/net/corda/contracts/CommercialPaperLegacy.kt @@ -36,7 +36,7 @@ class CommercialPaperLegacy : Contract { override val participants = listOf(owner) fun withoutOwner() = copy(owner = NULL_PARTY) - override fun withNewOwner(newOwner: AbstractParty) = Pair(Commands.Move(), copy(owner = newOwner)) + override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(Commands.Move(), copy(owner = newOwner)) override fun toString() = "${Emoji.newspaper}CommercialPaper(of $faceValue redeemable on $maturityDate by '$issuance', owned by $owner)" // Although kotlin is smart enough not to need these, as we are using the ICommercialPaperState, we need to declare them explicitly for use later, diff --git a/finance/src/main/kotlin/net/corda/contracts/asset/Cash.kt b/finance/src/main/kotlin/net/corda/contracts/asset/Cash.kt index 9b0ca94da2..5e51024f9a 100644 --- a/finance/src/main/kotlin/net/corda/contracts/asset/Cash.kt +++ b/finance/src/main/kotlin/net/corda/contracts/asset/Cash.kt @@ -108,7 +108,7 @@ class Cash : OnLedgerAsset() { override fun toString() = "${Emoji.bagOfCash}Cash($amount at ${amount.token.issuer} owned by $owner)" - override fun withNewOwner(newOwner: AbstractParty) = Pair(Commands.Move(), copy(owner = newOwner)) + override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(Commands.Move(), copy(owner = newOwner)) /** Object Relational Mapping support. */ override fun generateMappedObject(schema: MappedSchema): PersistentState { diff --git a/finance/src/main/kotlin/net/corda/contracts/asset/CommodityContract.kt b/finance/src/main/kotlin/net/corda/contracts/asset/CommodityContract.kt index e6697f2564..cf36ea7d7b 100644 --- a/finance/src/main/kotlin/net/corda/contracts/asset/CommodityContract.kt +++ b/finance/src/main/kotlin/net/corda/contracts/asset/CommodityContract.kt @@ -110,7 +110,7 @@ class CommodityContract : OnLedgerAsset : Contract { } } - override fun withNewOwner(newOwner: AbstractParty) = Pair(Commands.Move(), copy(beneficiary = newOwner)) + override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(Commands.Move(), copy(beneficiary = newOwner)) } // Just for grouping diff --git a/finance/src/test/kotlin/net/corda/contracts/DummyFungibleContract.kt b/finance/src/test/kotlin/net/corda/contracts/DummyFungibleContract.kt index e01f13618f..f8d78a6852 100644 --- a/finance/src/test/kotlin/net/corda/contracts/DummyFungibleContract.kt +++ b/finance/src/test/kotlin/net/corda/contracts/DummyFungibleContract.kt @@ -71,7 +71,7 @@ class DummyFungibleContract : OnLedgerAsset get() = listOf(owner) - override fun withNewOwner(newOwner: AbstractParty) = Pair(Commands.Create(), copy(owner = newOwner)) + override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(Commands.Create(), copy(owner = newOwner)) } interface Commands : CommandData { diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt index 0b34998c98..547d29be7b 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt @@ -8,6 +8,7 @@ import javafx.scene.shape.Circle import javafx.scene.shape.Line import javafx.util.Duration import net.corda.core.crypto.commonName +import net.corda.core.node.ScreenCoordinate import net.corda.core.utilities.ProgressTracker import net.corda.netmap.simulation.IRSSimulation import net.corda.testing.node.MockNetwork @@ -26,7 +27,7 @@ class VisualiserViewModel { inner class NodeWidget(val node: MockNetwork.MockNode, val innerDot: Circle, val outerDot: Circle, val longPulseDot: Circle, val pulseAnim: Animation, val longPulseAnim: Animation, val nameLabel: Label, val statusLabel: Label) { - fun position(nodeCoords: (node: MockNetwork.MockNode) -> Pair) { + fun position(nodeCoords: (node: MockNetwork.MockNode) -> ScreenCoordinate) { val (x, y) = nodeCoords(node) innerDot.centerX = x innerDot.centerY = y @@ -76,7 +77,7 @@ class VisualiserViewModel { } } - fun nodeMapCoords(node: MockNetwork.MockNode): Pair { + fun nodeMapCoords(node: MockNetwork.MockNode): ScreenCoordinate { // For an image of the whole world, we use: // return node.place.coordinate.project(mapImage.fitWidth, mapImage.fitHeight, 85.0511, -85.0511, -180.0, 180.0) @@ -90,7 +91,7 @@ class VisualiserViewModel { } } - fun nodeCircleCoords(type: NetworkMapVisualiser.NodeType, index: Int): Pair { + fun nodeCircleCoords(type: NetworkMapVisualiser.NodeType, index: Int): ScreenCoordinate { val stepRad: Double = when (type) { NetworkMapVisualiser.NodeType.BANK -> 2 * Math.PI / bankCount NetworkMapVisualiser.NodeType.SERVICE -> (2 * Math.PI / serviceCount) @@ -109,7 +110,7 @@ class VisualiserViewModel { val circleY = view.stageHeight / 2 + yOffset val x: Double = radius * Math.cos(tangentRad) + circleX val y: Double = radius * Math.sin(tangentRad) + circleY - return Pair(x, y) + return ScreenCoordinate(x, y) } fun createNodes() { diff --git a/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt b/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt index bf13dab4f3..92fb2c1084 100644 --- a/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt +++ b/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt @@ -21,7 +21,7 @@ data class DummyContract(override val legalContractReference: SecureHash = Secur override val participants: List get() = listOf(owner) - override fun withNewOwner(newOwner: AbstractParty) = Pair(Commands.Move(), copy(owner = newOwner)) + override fun withNewOwner(newOwner: AbstractParty) = CommandAndState(Commands.Move(), copy(owner = newOwner)) } /** diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt index 02cf2bd93b..9df6973b25 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt @@ -30,6 +30,7 @@ import net.corda.core.contracts.ContractState import net.corda.core.crypto.toBase58String import net.corda.core.identity.Party import net.corda.core.node.NodeInfo +import net.corda.core.node.ScreenCoordinate import net.corda.explorer.formatters.PartyNameFormatter import net.corda.explorer.model.CordaView import tornadofx.* @@ -122,11 +123,11 @@ class Network : CordaView() { contentDisplay = ContentDisplay.TOP val coordinate = Bindings.createObjectBinding({ // These coordinates are obtained when we generate the map using TileMill. - node.worldMapLocation?.coordinate?.project(mapPane.width, mapPane.height, 85.0511, -85.0511, -180.0, 180.0) ?: Pair(0.0, 0.0) + node.worldMapLocation?.coordinate?.project(mapPane.width, mapPane.height, 85.0511, -85.0511, -180.0, 180.0) ?: ScreenCoordinate(0.0, 0.0) }, arrayOf(mapPane.widthProperty(), mapPane.heightProperty())) // Center point of the label. - layoutXProperty().bind(coordinate.map { it.first - width / 2 }) - layoutYProperty().bind(coordinate.map { it.second - height / 4 }) + layoutXProperty().bind(coordinate.map { it.screenX - width / 2 }) + layoutYProperty().bind(coordinate.map { it.screenY - height / 4 }) } val button = node.renderButton(mapLabel)