From 71babc7019f1ffd3df5da441f1fb69848e93889f Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Mon, 6 Feb 2017 11:03:23 +0000 Subject: [PATCH] Remove use of full parties from contract states --- .../net/corda/core/contracts/Structures.kt | 3 +- .../net/corda/core/crypto/AnonymousParty.kt | 1 + .../kotlin/net/corda/core/crypto/Party.kt | 5 ++-- .../net/corda/core/node/services/Services.kt | 2 +- .../net/corda/core/serialization/Kryo.kt | 1 + .../net/corda/core/testing/Generators.kt | 8 ++++- .../net/corda/flows/TwoPartyDealFlow.kt | 2 +- .../kotlin/net/corda/contracts/asset/Cash.kt | 2 +- .../net/corda/contracts/asset/Obligation.kt | 23 +++++++++----- .../identity/InMemoryIdentityService.kt | 7 +---- .../node/services/messaging/RPCStructures.kt | 6 ++-- .../net/corda/node/utilities/JsonSupport.kt | 30 +++++++++++++++++-- .../kotlin/net/corda/irs/IRSDemoTest.kt | 7 +++-- .../main/kotlin/net/corda/irs/contract/IRS.kt | 11 +++---- .../net/corda/irs/flows/AutoOfferFlow.kt | 8 ++--- .../kotlin/net/corda/irs/flows/FixingFlow.kt | 3 +- .../net/corda/simulation/IRSSimulation.kt | 4 +-- .../kotlin/net/corda/simulation/Simulation.kt | 5 ++-- .../src/main/resources/example-irs-trade.json | 4 +-- .../src/main/resources/simulation/trade.json | 4 +-- .../kotlin/net/corda/irs/testing/IRSTests.kt | 8 ++--- .../kotlin/net/corda/vega/api/PortfolioApi.kt | 5 ++-- .../net/corda/vega/api/PortfolioApiUtils.kt | 6 ++-- .../net/corda/vega/api/SwapDataModel.kt | 2 +- .../kotlin/net/corda/vega/api/SwapDataView.kt | 2 +- .../net/corda/vega/contracts/IRSState.kt | 7 +++-- .../corda/vega/contracts/PortfolioState.kt | 7 +++-- .../net/corda/vega/contracts/SwapData.kt | 14 +++++---- .../net/corda/vega/flows/IRSTradeFlow.kt | 4 +-- .../kotlin/net/corda/vega/flows/SimmFlow.kt | 17 ++++++++--- .../net/corda/vega/flows/SimmRevaluation.kt | 9 +++--- .../main/kotlin/net/corda/explorer/Main.kt | 2 +- .../net/corda/loadtest/tests/CrossCashTest.kt | 5 ++-- .../net/corda/loadtest/tests/SelfIssueTest.kt | 2 +- 34 files changed, 141 insertions(+), 85 deletions(-) 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 79aceba0b4..83e8bfd802 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/Structures.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/Structures.kt @@ -290,7 +290,7 @@ interface DealState : LinearState { * separate process exchange certificates to ascertain identities. Thus decoupling identities from * [ContractState]s. * */ - val parties: List + val parties: List /** * Generate a partial transaction representing an agreement (command) to this deal, allowing a general @@ -351,6 +351,7 @@ inline fun Iterable>.filt * ledger. The reference is intended to be encrypted so it's meaningless to anyone other than the party. */ data class PartyAndReference(val party: AnonymousParty, val reference: OpaqueBytes) { + constructor(party: Party, reference: OpaqueBytes) : this(party.toAnonymous(), reference) override fun toString() = "${party}$reference" } diff --git a/core/src/main/kotlin/net/corda/core/crypto/AnonymousParty.kt b/core/src/main/kotlin/net/corda/core/crypto/AnonymousParty.kt index 30745dec02..be1603b665 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/AnonymousParty.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/AnonymousParty.kt @@ -15,6 +15,7 @@ open class AnonymousParty(val owningKey: CompositeKey) { /** Anonymised parties do not include any detail apart from owning key, so equality is dependent solely on the key */ override fun equals(other: Any?): Boolean = other is AnonymousParty && this.owningKey == other.owningKey override fun hashCode(): Int = owningKey.hashCode() + open fun toAnonymous() : AnonymousParty = this // Use the key as the bulk of the toString(), but include a human readable identifier as well, so that [Party] // can put in the key and actual name override fun toString() = "${owningKey.toBase58String()} " diff --git a/core/src/main/kotlin/net/corda/core/crypto/Party.kt b/core/src/main/kotlin/net/corda/core/crypto/Party.kt index bfb9a5c342..15fe8aab0f 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/Party.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/Party.kt @@ -23,5 +23,6 @@ import java.security.PublicKey class Party(val name: String, owningKey: CompositeKey) : AnonymousParty(owningKey) { /** A helper constructor that converts the given [PublicKey] in to a [CompositeKey] with a single node */ constructor(name: String, owningKey: PublicKey) : this(name, owningKey.composite) - override fun toString() = "${owningKey.toBase58String()} ($name)" -} \ No newline at end of file + override fun toAnonymous(): AnonymousParty = AnonymousParty(owningKey) + override fun toString() = "${owningKey.toBase58String()} (${name})" +} diff --git a/core/src/main/kotlin/net/corda/core/node/services/Services.kt b/core/src/main/kotlin/net/corda/core/node/services/Services.kt index a65e3a5a40..c5acba89eb 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/Services.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/Services.kt @@ -216,7 +216,7 @@ interface VaultService { } inline fun VaultService.linearHeadsOfType() = linearHeadsOfType_(T::class.java) -inline fun VaultService.dealsWith(party: Party) = linearHeadsOfType().values.filter { +inline fun VaultService.dealsWith(party: AnonymousParty) = linearHeadsOfType().values.filter { it.state.data.parties.any { it == party } } diff --git a/core/src/main/kotlin/net/corda/core/serialization/Kryo.kt b/core/src/main/kotlin/net/corda/core/serialization/Kryo.kt index bee92be51f..099ca7ffde 100644 --- a/core/src/main/kotlin/net/corda/core/serialization/Kryo.kt +++ b/core/src/main/kotlin/net/corda/core/serialization/Kryo.kt @@ -428,6 +428,7 @@ fun createKryo(k: Kryo = Kryo()): Kryo { addDefaultSerializer(SerializeAsToken::class.java, SerializeAsTokenSerializer()) // This is required to make all the unit tests pass + register(AnonymousParty::class.java) register(Party::class.java) // This ensures a NonEmptySetSerializer is constructed with an initial value. diff --git a/core/src/main/kotlin/net/corda/core/testing/Generators.kt b/core/src/main/kotlin/net/corda/core/testing/Generators.kt index 5247506ee1..ed6bcb2fd5 100644 --- a/core/src/main/kotlin/net/corda/core/testing/Generators.kt +++ b/core/src/main/kotlin/net/corda/core/testing/Generators.kt @@ -45,6 +45,12 @@ class CompositeKeyGenerator : Generator(CompositeKey::class.java) } } +class AnonymousPartyGenerator : Generator(AnonymousParty::class.java) { + override fun generate(random: SourceOfRandomness, status: GenerationStatus): AnonymousParty { + return AnonymousParty(CompositeKeyGenerator().generate(random, status)) + } +} + class PartyGenerator : Generator(Party::class.java) { override fun generate(random: SourceOfRandomness, status: GenerationStatus): Party { return Party(StringGenerator().generate(random, status), CompositeKeyGenerator().generate(random, status)) @@ -53,7 +59,7 @@ class PartyGenerator : Generator(Party::class.java) { class PartyAndReferenceGenerator : Generator(PartyAndReference::class.java) { override fun generate(random: SourceOfRandomness, status: GenerationStatus): PartyAndReference { - return PartyAndReference(PartyGenerator().generate(random, status), OpaqueBytes(random.nextBytes(16))) + return PartyAndReference(AnonymousPartyGenerator().generate(random, status), OpaqueBytes(random.nextBytes(16))) } } diff --git a/core/src/main/kotlin/net/corda/flows/TwoPartyDealFlow.kt b/core/src/main/kotlin/net/corda/flows/TwoPartyDealFlow.kt index 6e3556d85d..c874f328cf 100644 --- a/core/src/main/kotlin/net/corda/flows/TwoPartyDealFlow.kt +++ b/core/src/main/kotlin/net/corda/flows/TwoPartyDealFlow.kt @@ -300,7 +300,7 @@ object TwoPartyDealFlow { // And add a request for timestamping: it may be that none of the contracts need this! But it can't hurt // to have one. ptx.setTime(serviceHub.clock.instant(), 30.seconds) - return Pair(ptx, arrayListOf(deal.parties.single { it.name == serviceHub.myInfo.legalIdentity.name }.owningKey)) + return Pair(ptx, arrayListOf(deal.parties.single { it == serviceHub.myInfo.legalIdentity }.owningKey)) } } 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 0cce72c41b..bd90dacf0c 100644 --- a/finance/src/main/kotlin/net/corda/contracts/asset/Cash.kt +++ b/finance/src/main/kotlin/net/corda/contracts/asset/Cash.kt @@ -192,7 +192,7 @@ fun Iterable.sumCashOrZero(currency: Issued): Amount : Contract { data class State

( var lifecycle: Lifecycle = Lifecycle.NORMAL, /** Where the debt originates from (obligor) */ - val obligor: Party, + val obligor: AnonymousParty, val template: Terms

, val quantity: Long, /** The public key of the entity the contract pays to */ val beneficiary: CompositeKey ) : FungibleAsset>, NettableState, MultilateralNetState

> { + constructor(lifecycle: Lifecycle = Lifecycle.NORMAL, + obligor: Party, + template: Terms

, + quantity: Long, + beneficiary: CompositeKey) + : this(lifecycle, obligor.toAnonymous(), template, quantity, beneficiary) + override val amount: Amount>> = Amount(quantity, Issued(obligor.ref(0), template)) override val contract = OBLIGATION_PROGRAM_ID override val exitKeys: Collection = setOf(beneficiary) @@ -456,14 +463,14 @@ class Obligation

: Contract { * Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey. */ fun generateIssue(tx: TransactionBuilder, - obligor: Party, + obligor: AnonymousParty, issuanceDef: Terms

, pennies: Long, beneficiary: CompositeKey, notary: Party) { check(tx.inputStates().isEmpty()) check(tx.outputStates().map { it.data }.sumObligationsOrNull

() == null) - tx.addOutputState(State(Lifecycle.NORMAL, obligor, issuanceDef, pennies, beneficiary), notary) + tx.addOutputState(State(Lifecycle.NORMAL, obligor.toAnonymous(), issuanceDef, pennies, beneficiary), notary) tx.addCommand(Commands.Issue(), obligor.owningKey) } @@ -475,7 +482,7 @@ class Obligation

: Contract { "all states are in the normal lifecycle state " by (states.all { it.lifecycle == Lifecycle.NORMAL }) } val groups = states.groupBy { it.multilateralNetState } - val partyLookup = HashMap() + val partyLookup = HashMap() val signers = states.map { it.beneficiary }.union(states.map { it.obligor.owningKey }).toSet() // Create a lookup table of the party that each public key represents. @@ -700,13 +707,13 @@ fun

Iterable.sumObligationsOrZero(issuanceDef: Issued>().filter { it.lifecycle == Obligation.Lifecycle.NORMAL }.map { it.amount }.sumOrZero(issuanceDef) infix fun Obligation.State.at(dueBefore: Instant) = copy(template = template.copy(dueBefore = dueBefore)) -infix fun Obligation.State.between(parties: Pair) = copy(obligor = parties.first, beneficiary = parties.second) +infix fun Obligation.State.between(parties: Pair) = copy(obligor = parties.first.toAnonymous(), beneficiary = parties.second) infix fun Obligation.State.`owned by`(owner: CompositeKey) = copy(beneficiary = owner) -infix fun Obligation.State.`issued by`(party: Party) = copy(obligor = party) +infix fun Obligation.State.`issued by`(party: AnonymousParty) = copy(obligor = party.toAnonymous()) // For Java users: @Suppress("unused") fun Obligation.State.ownedBy(owner: CompositeKey) = copy(beneficiary = owner) -@Suppress("unused") fun Obligation.State.issuedBy(party: Party) = copy(obligor = party) +@Suppress("unused") fun Obligation.State.issuedBy(party: AnonymousParty) = copy(obligor = party) /** A randomly generated key. */ val DUMMY_OBLIGATION_ISSUER_KEY by lazy { entropyToKeyPair(BigInteger.valueOf(10)) } @@ -716,4 +723,4 @@ val DUMMY_OBLIGATION_ISSUER by lazy { Party("Snake Oil Issuer", DUMMY_OBLIGATION val Issued.OBLIGATION_DEF: Obligation.Terms get() = Obligation.Terms(nonEmptySetOf(Cash().legalContractReference), nonEmptySetOf(this), TEST_TX_TIME) val Amount>.OBLIGATION: Obligation.State - get() = Obligation.State(Obligation.Lifecycle.NORMAL, DUMMY_OBLIGATION_ISSUER, token.OBLIGATION_DEF, quantity, NullCompositeKey) + get() = Obligation.State(Obligation.Lifecycle.NORMAL, DUMMY_OBLIGATION_ISSUER.toAnonymous(), token.OBLIGATION_DEF, quantity, NullCompositeKey) diff --git a/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt b/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt index 639bc7e951..210cb3c131 100644 --- a/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt +++ b/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt @@ -28,11 +28,6 @@ class InMemoryIdentityService() : SingletonSerializeAsToken(), IdentityService { override fun partyFromKey(key: CompositeKey): Party? = keyToParties[key] override fun partyFromName(name: String): Party? = nameToParties[name] - override fun partyFromAnonymous(party: AnonymousParty): Party? { - return if (party is Party) - party - else - partyFromKey(party.owningKey) - } + override fun partyFromAnonymous(party: AnonymousParty): Party? = partyFromKey(party.owningKey) override fun partyFromAnonymous(partyRef: PartyAndReference) = partyFromAnonymous(partyRef.party) } diff --git a/node/src/main/kotlin/net/corda/node/services/messaging/RPCStructures.kt b/node/src/main/kotlin/net/corda/node/services/messaging/RPCStructures.kt index d602a5ac3d..ff91af2992 100644 --- a/node/src/main/kotlin/net/corda/node/services/messaging/RPCStructures.kt +++ b/node/src/main/kotlin/net/corda/node/services/messaging/RPCStructures.kt @@ -16,10 +16,7 @@ import de.javakaffee.kryoserializers.guava.* import net.corda.contracts.asset.Cash import net.corda.core.ErrorOr import net.corda.core.contracts.* -import net.corda.core.crypto.CompositeKey -import net.corda.core.crypto.DigitalSignature -import net.corda.core.crypto.Party -import net.corda.core.crypto.SecureHash +import net.corda.core.crypto.* import net.corda.core.flows.FlowException import net.corda.core.flows.IllegalFlowLogicException import net.corda.core.flows.StateMachineRunId @@ -140,6 +137,7 @@ private class RPCKryo(observableSerializer: Serializer>? = null) register(SignedTransaction::class.java, ImmutableClassSerializer(SignedTransaction::class)) register(WireTransaction::class.java, WireTransactionSerializer) register(SerializedBytes::class.java, SerializedBytesSerializer) + register(AnonymousParty::class.java) register(Party::class.java) register(Array(0,{}).javaClass) register(Class::class.java, ClassSerializer) diff --git a/node/src/main/kotlin/net/corda/node/utilities/JsonSupport.kt b/node/src/main/kotlin/net/corda/node/utilities/JsonSupport.kt index 20d06f4e67..7b8c8380f2 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/JsonSupport.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/JsonSupport.kt @@ -30,16 +30,20 @@ import java.time.LocalDateTime object JsonSupport { interface PartyObjectMapper { fun partyFromName(partyName: String): Party? + fun partyFromKey(owningKey: CompositeKey): Party? } class RpcObjectMapper(val rpc: CordaRPCOps) : PartyObjectMapper, ObjectMapper() { override fun partyFromName(partyName: String): Party? = rpc.partyFromName(partyName) + override fun partyFromKey(owningKey: CompositeKey): Party? = rpc.partyFromKey(owningKey) } class IdentityObjectMapper(val identityService: IdentityService) : PartyObjectMapper, ObjectMapper(){ - override fun partyFromName(partyName: String) = identityService.partyFromName(partyName) + override fun partyFromName(partyName: String): Party? = identityService.partyFromName(partyName) + override fun partyFromKey(owningKey: CompositeKey): Party? = identityService.partyFromKey(owningKey) } class NoPartyObjectMapper: PartyObjectMapper, ObjectMapper() { - override fun partyFromName(partyName: String) = throw UnsupportedOperationException() + override fun partyFromName(partyName: String): Party? = throw UnsupportedOperationException() + override fun partyFromKey(owningKey: CompositeKey): Party? = throw UnsupportedOperationException() } val javaTimeModule: Module by lazy { @@ -53,6 +57,8 @@ object JsonSupport { val cordaModule: Module by lazy { SimpleModule("core").apply { + addSerializer(AnonymousParty::class.java, AnonymousPartySerializer) + addDeserializer(AnonymousParty::class.java, AnonymousPartyDeserializer) addSerializer(Party::class.java, PartySerializer) addDeserializer(Party::class.java, PartyDeserializer) addSerializer(BigDecimal::class.java, ToStringSerializer) @@ -120,6 +126,26 @@ object JsonSupport { } + object AnonymousPartySerializer : JsonSerializer() { + override fun serialize(obj: AnonymousParty, generator: JsonGenerator, provider: SerializerProvider) { + generator.writeString(obj.owningKey.toBase58String()) + } + } + + object AnonymousPartyDeserializer : JsonDeserializer() { + override fun deserialize(parser: JsonParser, context: DeserializationContext): AnonymousParty { + if (parser.currentToken == JsonToken.FIELD_NAME) { + parser.nextToken() + } + + val mapper = parser.codec as PartyObjectMapper + // TODO this needs to use some industry identifier(s) instead of these keys + val key = CompositeKey.parseFromBase58(parser.text) + val party = mapper.partyFromKey(key) ?: throw JsonParseException(parser, "Could not find a Party with key ${parser.text}") + return party.toAnonymous() + } + } + object PartySerializer : JsonSerializer() { override fun serialize(obj: Party, generator: JsonGenerator, provider: SerializerProvider) { generator.writeString(obj.name) diff --git a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt index 9376378a51..ab739ac11e 100644 --- a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt +++ b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt @@ -2,6 +2,7 @@ package net.corda.irs import com.google.common.net.HostAndPort import com.google.common.util.concurrent.Futures +import net.corda.core.crypto.Party import net.corda.core.getOrThrow import net.corda.core.node.services.ServiceInfo import net.corda.irs.api.NodeInterestRates @@ -44,7 +45,7 @@ class IRSDemoTest : IntegrationTestCategory { val nextFixingDates = getFixingDateObservable(nodeA.configuration) runUploadRates(controllerAddr) - runTrade(nodeAAddr) + runTrade(nodeAAddr, nodeA.nodeInfo.legalIdentity, nodeB.nodeInfo.legalIdentity) // Wait until the initial trade and all scheduled fixings up to the current date have finished nextFixingDates.first { it == null || it > currentDate } @@ -72,9 +73,11 @@ class IRSDemoTest : IntegrationTestCategory { assert(putJson(url, "\"$futureDate\"")) } - private fun runTrade(nodeAddr: HostAndPort) { + private fun runTrade(nodeAddr: HostAndPort, fixedRatePayer: Party, floatingRatePayer: Party) { val fileContents = IOUtils.toString(Thread.currentThread().contextClassLoader.getResourceAsStream("example-irs-trade.json")) val tradeFile = fileContents.replace("tradeXXX", "trade1") + .replace("fixedRatePayerKey", fixedRatePayer.owningKey.toBase58String()) + .replace("floatingRatePayerKey", floatingRatePayer.owningKey.toBase58String()) val url = URL("http://$nodeAddr/api/irs/deals") assert(postJson(url, tradeFile)) } diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt index 60c30dae1f..b4d0273e68 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt @@ -2,6 +2,7 @@ package net.corda.irs.contract import net.corda.core.contracts.* import net.corda.core.contracts.clauses.* +import net.corda.core.crypto.AnonymousParty import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.Party import net.corda.core.crypto.SecureHash @@ -304,7 +305,7 @@ class InterestRateSwap() : Contract { } open class FixedLeg( - var fixedRatePayer: Party, + var fixedRatePayer: AnonymousParty, notional: Amount, paymentFrequency: Frequency, effectiveDate: LocalDate, @@ -343,7 +344,7 @@ class InterestRateSwap() : Contract { override fun hashCode() = super.hashCode() + 31 * Objects.hash(fixedRatePayer, fixedRate, rollConvention) // Can't autogenerate as not a data class :-( - fun copy(fixedRatePayer: Party = this.fixedRatePayer, + fun copy(fixedRatePayer: AnonymousParty = this.fixedRatePayer, notional: Amount = this.notional, paymentFrequency: Frequency = this.paymentFrequency, effectiveDate: LocalDate = this.effectiveDate, @@ -365,7 +366,7 @@ class InterestRateSwap() : Contract { } open class FloatingLeg( - var floatingRatePayer: Party, + var floatingRatePayer: AnonymousParty, notional: Amount, paymentFrequency: Frequency, effectiveDate: LocalDate, @@ -423,7 +424,7 @@ class InterestRateSwap() : Contract { index, indexSource, indexTenor) - fun copy(floatingRatePayer: Party = this.floatingRatePayer, + fun copy(floatingRatePayer: AnonymousParty = this.floatingRatePayer, notional: Amount = this.notional, paymentFrequency: Frequency = this.paymentFrequency, effectiveDate: LocalDate = this.effectiveDate, @@ -672,7 +673,7 @@ class InterestRateSwap() : Contract { return fixedLeg.fixedRatePayer.owningKey.containsAny(ourKeys) || floatingLeg.floatingRatePayer.owningKey.containsAny(ourKeys) } - override val parties: List + override val parties: List get() = listOf(fixedLeg.fixedRatePayer, floatingLeg.floatingRatePayer) override fun nextScheduledActivity(thisStateRef: StateRef, flowLogicRefFactory: FlowLogicRefFactory): ScheduledActivity? { diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt index 2d1cf59900..da9a9f862c 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt @@ -2,7 +2,7 @@ package net.corda.irs.flows import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.DealState -import net.corda.core.crypto.Party +import net.corda.core.crypto.AnonymousParty import net.corda.core.flows.FlowLogic import net.corda.core.node.CordaPluginRegistry import net.corda.core.node.PluginServiceHub @@ -65,7 +65,7 @@ object AutoOfferFlow { require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } val notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity // need to pick which ever party is not us - val otherParty = notUs(dealToBeOffered.parties).single() + val otherParty = notUs(dealToBeOffered.parties).map { serviceHub.identityService.partyFromAnonymous(it) }.requireNoNulls().single() progressTracker.currentStep = DEALING val myKey = serviceHub.legalIdentityKey val instigator = Instigator( @@ -78,8 +78,8 @@ object AutoOfferFlow { return stx } - private fun notUs(parties: List): List { - val notUsParties: MutableList = arrayListOf() + private fun notUs(parties: List): List { + val notUsParties: MutableList = arrayListOf() for (party in parties) { if (serviceHub.myInfo.legalIdentity != party) { notUsParties.add(party) diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt index 40ad8a49d0..598affee78 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt @@ -151,8 +151,9 @@ object FixingFlow { val myKey = serviceHub.myInfo.legalIdentity.owningKey if (parties[0].owningKey == myKey) { val fixing = FixingSession(ref, fixableDeal.oracleType) + val counterparty = serviceHub.identityService.partyFromAnonymous(parties[1]) ?: throw IllegalStateException("Cannot resolve floater party") // Start the Floater which will then kick-off the Fixer - subFlow(Floater(parties[1], fixing)) + subFlow(Floater(counterparty, fixing)) } } } diff --git a/samples/irs-demo/src/main/kotlin/net/corda/simulation/IRSSimulation.kt b/samples/irs-demo/src/main/kotlin/net/corda/simulation/IRSSimulation.kt index 2e9c984aa9..fa2fd9e2d1 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/simulation/IRSSimulation.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/simulation/IRSSimulation.kt @@ -117,8 +117,8 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten // have the convenient copy() method that'd let us make small adjustments. Instead they're partly mutable. // TODO: We should revisit this in post-Excalibur cleanup and fix, e.g. by introducing an interface. val irs = om.readValue(javaClass.classLoader.getResource("simulation/trade.json")) - irs.fixedLeg.fixedRatePayer = node1.info.legalIdentity - irs.floatingLeg.floatingRatePayer = node2.info.legalIdentity + irs.fixedLeg.fixedRatePayer = node1.info.legalIdentity.toAnonymous() + irs.floatingLeg.floatingRatePayer = node2.info.legalIdentity.toAnonymous() @Suppress("UNCHECKED_CAST") val acceptorTx = node2.initiateSingleShotFlow(Instigator::class) { Acceptor(it) }.flatMap { diff --git a/samples/irs-demo/src/main/kotlin/net/corda/simulation/Simulation.kt b/samples/irs-demo/src/main/kotlin/net/corda/simulation/Simulation.kt index bfb5dd8dab..72e0cddbf8 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/simulation/Simulation.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/simulation/Simulation.kt @@ -75,8 +75,9 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, } fun createAll(): List { - return bankLocations.map { - network.createNode(networkMap.info.address, start = false, nodeFactory = this) as SimulatedNode + return bankLocations.mapIndexed { i, location -> + // Use deterministic seeds so the simulation is stable. Needed so that party owning keys are stable. + network.createNode(networkMap.info.address, start = false, nodeFactory = this, entropyRoot = BigInteger.valueOf(i.toLong())) as SimulatedNode } } } diff --git a/samples/irs-demo/src/main/resources/example-irs-trade.json b/samples/irs-demo/src/main/resources/example-irs-trade.json index d0d33c09e5..98c1572dbc 100644 --- a/samples/irs-demo/src/main/resources/example-irs-trade.json +++ b/samples/irs-demo/src/main/resources/example-irs-trade.json @@ -1,6 +1,6 @@ { "fixedLeg": { - "fixedRatePayer": "Bank A", + "fixedRatePayer": "fixedRatePayerKey", "notional": { "quantity": 2500000000, "token": "EUR" @@ -25,7 +25,7 @@ "interestPeriodAdjustment": "Adjusted" }, "floatingLeg": { - "floatingRatePayer": "Bank B", + "floatingRatePayer": "floatingRatePayerKey", "notional": { "quantity": 2500000000, "token": "EUR" diff --git a/samples/irs-demo/src/main/resources/simulation/trade.json b/samples/irs-demo/src/main/resources/simulation/trade.json index 36c73586a4..d19905e240 100644 --- a/samples/irs-demo/src/main/resources/simulation/trade.json +++ b/samples/irs-demo/src/main/resources/simulation/trade.json @@ -1,6 +1,6 @@ { "fixedLeg": { - "fixedRatePayer": "Bank A", + "fixedRatePayer": "bzs7kfAFKFTtGhxNHeN7eiqufP9Q3p9hDvSTi8AyoRAwiLK8ZZ", "notional": { "quantity": 2500000000, "token": "USD" @@ -25,7 +25,7 @@ "interestPeriodAdjustment": "Adjusted" }, "floatingLeg": { - "floatingRatePayer": "Bank B", + "floatingRatePayer": "bzs7kf3Zc6J8mgNyH2ZddNRp3wzQt8MnPMT4zMYWgouHB4Uro5", "notional": { "quantity": 2500000000, "token": "USD" diff --git a/samples/irs-demo/src/test/kotlin/net/corda/irs/testing/IRSTests.kt b/samples/irs-demo/src/test/kotlin/net/corda/irs/testing/IRSTests.kt index 603208f895..47f8644ef8 100644 --- a/samples/irs-demo/src/test/kotlin/net/corda/irs/testing/IRSTests.kt +++ b/samples/irs-demo/src/test/kotlin/net/corda/irs/testing/IRSTests.kt @@ -20,7 +20,7 @@ fun createDummyIRS(irsSelect: Int): InterestRateSwap.State { 1 -> { val fixedLeg = InterestRateSwap.FixedLeg( - fixedRatePayer = MEGA_CORP, + fixedRatePayer = MEGA_CORP.toAnonymous(), notional = 15900000.DOLLARS, paymentFrequency = Frequency.SemiAnnual, effectiveDate = LocalDate.of(2016, 3, 10), @@ -39,7 +39,7 @@ fun createDummyIRS(irsSelect: Int): InterestRateSwap.State { ) val floatingLeg = InterestRateSwap.FloatingLeg( - floatingRatePayer = MINI_CORP, + floatingRatePayer = MINI_CORP.toAnonymous(), notional = 15900000.DOLLARS, paymentFrequency = Frequency.Quarterly, effectiveDate = LocalDate.of(2016, 3, 10), @@ -110,7 +110,7 @@ fun createDummyIRS(irsSelect: Int): InterestRateSwap.State { // I did a mock up start date 10/03/2015 – 10/03/2025 so you have 5 cashflows on float side that have been preset the rest are unknown val fixedLeg = InterestRateSwap.FixedLeg( - fixedRatePayer = MEGA_CORP, + fixedRatePayer = MEGA_CORP.toAnonymous(), notional = 25000000.DOLLARS, paymentFrequency = Frequency.SemiAnnual, effectiveDate = LocalDate.of(2015, 3, 10), @@ -129,7 +129,7 @@ fun createDummyIRS(irsSelect: Int): InterestRateSwap.State { ) val floatingLeg = InterestRateSwap.FloatingLeg( - floatingRatePayer = MINI_CORP, + floatingRatePayer = MINI_CORP.toAnonymous(), notional = 25000000.DOLLARS, paymentFrequency = Frequency.Quarterly, effectiveDate = LocalDate.of(2015, 3, 10), diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt index 1127fc6c3f..3c35091a69 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt @@ -4,6 +4,7 @@ import com.opengamma.strata.basics.currency.MultiCurrencyAmount import net.corda.core.contracts.DealState import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.filterStatesOfType +import net.corda.core.crypto.AnonymousParty import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.Party import net.corda.core.getOrThrow @@ -33,7 +34,7 @@ class PortfolioApi(val rpc: CordaRPCOps) { private val ownParty: Party get() = rpc.nodeIdentity().legalIdentity private val portfolioUtils = PortfolioApiUtils(ownParty) - private inline fun dealsWith(party: Party): List> { + private inline fun dealsWith(party: AnonymousParty): List> { return rpc.vaultAndUpdates().first.filterStatesOfType().filter { it.state.data.parties.any { it == party } } } @@ -220,7 +221,7 @@ class PortfolioApi(val rpc: CordaRPCOps) { return withParty(partyName) { party -> withPortfolio(party) { state -> if (state.valuation != null) { - val isValuer = state.valuer.name == ownParty.name + val isValuer = state.valuer as AnonymousParty == ownParty val rawMtm = state.valuation.presentValues.map { it.value.amounts.first().amount }.reduce { a, b -> a + b } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApiUtils.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApiUtils.kt index 9105fc2d11..2e1c488adf 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApiUtils.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApiUtils.kt @@ -122,7 +122,7 @@ class PortfolioApiUtils(private val ownParty: Party) { val ref: String) fun createTradeView(state: IRSState): TradeView { - val trade = if (state.buyer.name == ownParty.name) state.swap.toFloatingLeg() else state.swap.toFloatingLeg() + val trade = if (state.buyer == ownParty) state.swap.toFloatingLeg() else state.swap.toFloatingLeg() val fixedLeg = trade.product.legs.first { it.type == SwapLegType.FIXED } as RateCalculationSwapLeg val floatingLeg = trade.product.legs.first { it.type != SwapLegType.FIXED } as RateCalculationSwapLeg val fixedRate = fixedLeg.calculation as FixedRateCalculation @@ -130,7 +130,7 @@ class PortfolioApiUtils(private val ownParty: Party) { return TradeView( fixedLeg = mapOf( - "fixedRatePayer" to state.buyer.name, + "fixedRatePayer" to state.buyer.owningKey.toBase58String(), "notional" to mapOf( "token" to fixedLeg.currency.code, "quantity" to fixedLeg.notionalSchedule.amount.initialValue @@ -146,7 +146,7 @@ class PortfolioApiUtils(private val ownParty: Party) { "paymentCalendar" to mapOf() // TODO ), floatingLeg = mapOf( - "floatingRatePayer" to state.seller.name, + "floatingRatePayer" to state.seller.owningKey.toBase58String(), "notional" to mapOf( "token" to floatingLeg.currency.code, "quantity" to floatingLeg.notionalSchedule.amount.initialValue diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/SwapDataModel.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/SwapDataModel.kt index f3ebfca2e1..a428de20d3 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/SwapDataModel.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/SwapDataModel.kt @@ -27,7 +27,7 @@ data class SwapDataModel( */ fun toData(buyer: Party, seller: Party): SwapData { return SwapData( - Pair("swap", id), Pair("party", buyer.name), Pair("party", seller.name), description, tradeDate, convention, startDate, endDate, notional, fixedRate + Pair("swap", id), Pair("party", buyer.owningKey), Pair("party", seller.owningKey), description, tradeDate, convention, startDate, endDate, notional, fixedRate ) } } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/SwapDataView.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/SwapDataView.kt index 1b95df95d2..3af0ea999b 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/SwapDataView.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/SwapDataView.kt @@ -30,7 +30,7 @@ data class SwapDataView( fun SwapData.toView(viewingParty: Party, portfolio: Portfolio? = null, presentValue: MultiCurrencyAmount? = null, IM: InitialMarginTriple? = null): SwapDataView { - val isBuyer = viewingParty.name == buyer.second + val isBuyer = viewingParty.owningKey == buyer.second val trade = if (isBuyer) toFixedLeg() else toFloatingLeg() val leg = getLegForParty(viewingParty) val sdv = SwapDataView( diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt index 40de703256..2a8abbb0ac 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt @@ -4,6 +4,7 @@ import net.corda.core.contracts.Command import net.corda.core.contracts.DealState import net.corda.core.contracts.TransactionType import net.corda.core.contracts.UniqueIdentifier +import net.corda.core.crypto.AnonymousParty import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.Party import net.corda.core.transactions.TransactionBuilder @@ -15,12 +16,12 @@ import java.security.PublicKey * TODO: Merge with the existing demo IRS code. */ data class IRSState(val swap: SwapData, - val buyer: Party, - val seller: Party, + val buyer: AnonymousParty, + val seller: AnonymousParty, override val contract: OGTrade, override val linearId: UniqueIdentifier = UniqueIdentifier(swap.id.first + swap.id.second)) : DealState { override val ref: String = linearId.externalId!! // Same as the constructor for UniqueIdentified - override val parties: List get() = listOf(buyer, seller) + override val parties: List get() = listOf(buyer, seller) override fun isRelevant(ourKeys: Set): Boolean { return parties.flatMap { it.owningKey.keys }.intersect(ourKeys).isNotEmpty() diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt index 35704e5b64..ae98720e7c 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/PortfolioState.kt @@ -1,6 +1,7 @@ package net.corda.vega.contracts import net.corda.core.contracts.* +import net.corda.core.crypto.AnonymousParty import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.Party import net.corda.core.flows.FlowLogicRefFactory @@ -17,16 +18,16 @@ import java.time.temporal.ChronoUnit */ data class PortfolioState(val portfolio: List, override val contract: PortfolioSwap, - private val _parties: Pair, + private val _parties: Pair, val valuationDate: LocalDate, val valuation: PortfolioValuation? = null, override val linearId: UniqueIdentifier = UniqueIdentifier()) : RevisionedState, SchedulableState, DealState { data class Update(val portfolio: List? = null, val valuation: PortfolioValuation? = null) - override val parties: List get() = _parties.toList() + override val parties: List get() = _parties.toList() override val ref: String = linearId.toString() - val valuer: Party get() = parties[0] + val valuer: AnonymousParty get() = parties[0] override val participants: List get() = parties.map { it.owningKey } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/SwapData.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/SwapData.kt index 70c58c3691..b8832df629 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/SwapData.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/SwapData.kt @@ -9,6 +9,8 @@ import com.opengamma.strata.product.common.BuySell import com.opengamma.strata.product.swap.SwapTrade import com.opengamma.strata.product.swap.type.FixedIborSwapConvention import com.opengamma.strata.product.swap.type.FixedIborSwapConventions +import net.corda.core.crypto.AnonymousParty +import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.Party import java.math.BigDecimal import java.time.LocalDate @@ -36,8 +38,8 @@ data class FloatingLeg(val _notional: BigDecimal, override val notional: BigDeci */ data class SwapData( val id: Pair, - val buyer: Pair, - val seller: Pair, + val buyer: Pair, + val seller: Pair, val description: String, val tradeDate: LocalDate, val convention: String, @@ -46,8 +48,8 @@ data class SwapData( val notional: BigDecimal, val fixedRate: BigDecimal) { - fun getLegForParty(party: Party): Leg { - return if (party.name == buyer.second) FixedLeg(notional) else FloatingLeg(notional) + fun getLegForParty(party: AnonymousParty): Leg { + return if (party == buyer.second) FixedLeg(notional) else FloatingLeg(notional) } fun toFixedLeg(): SwapTrade { @@ -58,11 +60,11 @@ data class SwapData( return getTrade(BuySell.SELL, Pair("party", seller.second)) } - private fun getTrade(buySell: BuySell, party: Pair): SwapTrade { + private fun getTrade(buySell: BuySell, party: Pair): SwapTrade { val tradeInfo = TradeInfo.builder() .id(StandardId.of(id.first, id.second)) .addAttribute(TradeAttributeType.DESCRIPTION, description) - .counterparty(StandardId.of(party.first, party.second)) + .counterparty(StandardId.of(party.first, party.second.toBase58String())) .build() // TODO: Fix below to be correct - change tenor and reference data return getSwapConvention(convention).createTrade(startDate, Tenor.TENOR_4Y, buySell, notional.toDouble(), fixedRate.toDouble(), ReferenceData.standard()) 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 822c104c23..2117d65a8d 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 @@ -22,12 +22,12 @@ object IRSTradeFlow { val notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity val myIdentity = serviceHub.myInfo.legalIdentity val (buyer, seller) = - if (swap.buyer.second == myIdentity.name) { + if (swap.buyer.second == myIdentity.owningKey) { Pair(myIdentity, otherParty) } else { Pair(otherParty, myIdentity) } - val offer = IRSState(swap, buyer, seller, OGTrade()) + val offer = IRSState(swap, buyer.toAnonymous(), seller.toAnonymous(), OGTrade()) logger.info("Handshake finished, sending IRS trade offer message") val otherPartyAgreeFlag = sendAndReceive(otherParty, OfferMessage(notary, offer)).unwrap { it } 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 6617862b7c..a32ce86d32 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 @@ -12,6 +12,7 @@ import com.opengamma.strata.pricer.rate.ImmutableRatesProvider import com.opengamma.strata.pricer.swap.DiscountingSwapProductPricer import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.StateRef +import net.corda.core.crypto.AnonymousParty import net.corda.core.crypto.Party import net.corda.core.flows.FlowLogic import net.corda.core.messaging.Ack @@ -59,7 +60,7 @@ object SimmFlow { @Suspendable override fun call(): RevisionedState { - logger.debug("Calling from: ${serviceHub.myInfo.legalIdentity.name}. Sending to: ${otherParty.name}") + logger.debug("Calling from: ${serviceHub.myInfo.legalIdentity}. Sending to: ${otherParty}") require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity myIdentity = serviceHub.myInfo.legalIdentity @@ -80,7 +81,7 @@ object SimmFlow { @Suspendable private fun agreePortfolio(portfolio: Portfolio) { logger.info("Agreeing portfolio") - val parties = Pair(myIdentity, otherParty) + val parties = Pair(myIdentity.toAnonymous(), otherParty.toAnonymous()) val portfolioState = PortfolioState(portfolio.refs, PortfolioSwap(), parties, valuationDate) send(otherParty, OfferMessage(notary, portfolioState, existing?.ref, valuationDate)) @@ -102,8 +103,9 @@ object SimmFlow { logger.info("Agreeing valuations") val state = stateRef.state.data val portfolio = state.portfolio.toStateAndRef(serviceHub).toPortfolio() - val valuer = state.valuer - val valuation = agreeValuation(portfolio, valuationDate, valuer) + val valuer = serviceHub.identityService.partyFromAnonymous(state.valuer) + require(valuer != null) { "Valuer party must be known to this node" } + val valuation = agreeValuation(portfolio, valuationDate, valuer!!) val update = PortfolioState.Update(valuation = valuation) return subFlow(StateRevisionFlow.Requester(stateRef, update), shareParentSessions = true).state.data } @@ -213,6 +215,13 @@ object SimmFlow { return receive(replyToParty).unwrap { it == true } } + @Suspendable + private fun agreeValuation(portfolio: Portfolio, asOf: LocalDate, valuer: AnonymousParty): PortfolioValuation { + val valuerParty = serviceHub.identityService.partyFromAnonymous(valuer) + require(valuerParty != null) + return agreeValuation(portfolio, asOf, valuerParty!!) + } + /** * So this is the crux of the Simm Agreement flow * It needs to do several things - which are mainly defined by the analytics engine we are using - which in this diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt index d4a339bc67..2a184dd73e 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt @@ -17,10 +17,11 @@ object SimmRevaluation { override fun call(): Unit { val stateAndRef = serviceHub.vaultService.linearHeadsOfType().values.first { it.ref == curStateRef } val curState = stateAndRef.state.data - val myIdentity = serviceHub.myInfo.legalIdentity - if (myIdentity.name == curState.parties[0].name) { - val otherParty = curState.parties[1] - subFlow(SimmFlow.Requester(otherParty, valuationDate, stateAndRef)) + val myIdentity = serviceHub.myInfo.legalIdentity.toAnonymous() + if (myIdentity == curState.parties[0]) { + val otherParty = serviceHub.identityService.partyFromAnonymous(curState.parties[1]) + require (otherParty != null) { "Other party must be known by this node" } + subFlow(SimmFlow.Requester(otherParty!!, valuationDate, stateAndRef)) } } } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt index b7e1712841..e42537292e 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt @@ -169,7 +169,7 @@ fun main(args: Array) { val eventGenerator = EventGenerator( parties = listOf(aliceNode.nodeInfo.legalIdentity, bobNode.nodeInfo.legalIdentity), notary = notaryNode.nodeInfo.notaryIdentity, - issuers = listOf(issuerNodeGBP.nodeInfo.legalIdentity,issuerNodeUSD.nodeInfo.legalIdentity) + issuers = listOf(issuerNodeGBP.nodeInfo.legalIdentity, issuerNodeUSD.nodeInfo.legalIdentity) ) val issuerGBPEventGenerator = EventGenerator( parties = listOf(issuerNodeGBP.nodeInfo.legalIdentity, aliceNode.nodeInfo.legalIdentity, bobNode.nodeInfo.legalIdentity), diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/CrossCashTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/CrossCashTest.kt index e9b53de537..d3a0fb3525 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/CrossCashTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/CrossCashTest.kt @@ -7,7 +7,6 @@ import net.corda.core.contracts.Issued import net.corda.core.contracts.PartyAndReference import net.corda.core.contracts.USD import net.corda.core.crypto.AnonymousParty -import net.corda.core.crypto.Party import net.corda.core.flows.FlowException import net.corda.core.getOrThrow import net.corda.core.messaging.startFlow @@ -108,7 +107,7 @@ data class CrossCashState( it.value.map { val notifier = it.key " $notifier: [" + it.value.map { - Issued(PartyAndReference(it.first, OpaqueBytes.of(0)), it.second) + Issued(PartyAndReference(it.first.toAnonymous(), OpaqueBytes.of(0)), it.second) }.joinToString(",") + "]" }.joinToString("\n") }.joinToString("\n") @@ -126,7 +125,7 @@ val crossCashTest = LoadTest( val quantities = state.nodeVaults[node.info.legalIdentity] ?: mapOf() val possibleRecipients = nodeMap.keys.toList() val moves = quantities.map { - it.value.toDouble() / 1000 to generateMove(it.value, USD, it.key, possibleRecipients) + it.value.toDouble() / 1000 to generateMove(it.value, USD, it.key.toAnonymous(), possibleRecipients) } val exits = quantities.mapNotNull { if (it.key == node.info.legalIdentity) { diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt index e856f08913..53f075d0ad 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt @@ -79,7 +79,7 @@ val selfIssueTest = LoadTest( val state = it.state.data if (state is Cash.State) { val issuer = state.amount.token.issuer.party - if (issuer == node.info.legalIdentity) { + if (issuer == node.info.legalIdentity as AnonymousParty) { selfIssueVaults.put(issuer, (selfIssueVaults[issuer] ?: 0L) + state.amount.quantity) } }