mirror of
https://github.com/corda/corda.git
synced 2025-02-25 11:03:01 +00:00
Enforce separation of Party and AnonymousParty
This commit is contained in:
parent
fa33336d38
commit
ed093cdb9d
22
core/src/main/kotlin/net/corda/core/crypto/AbstractParty.kt
Normal file
22
core/src/main/kotlin/net/corda/core/crypto/AbstractParty.kt
Normal file
@ -0,0 +1,22 @@
|
||||
package net.corda.core.crypto
|
||||
|
||||
import net.corda.core.contracts.PartyAndReference
|
||||
import net.corda.core.serialization.OpaqueBytes
|
||||
import java.security.PublicKey
|
||||
|
||||
/**
|
||||
* An [AbstractParty] contains the common elements of [Party] and [AnonymousParty], specifically the owning key of
|
||||
* the party. In most cases [Party] or [AnonymousParty] should be used, depending on use-case.
|
||||
*/
|
||||
abstract class AbstractParty(val owningKey: CompositeKey) {
|
||||
/** A helper constructor that converts the given [PublicKey] in to a [CompositeKey] with a single node */
|
||||
constructor(owningKey: PublicKey) : this(owningKey.composite)
|
||||
|
||||
/** 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 AbstractParty && this.owningKey == other.owningKey
|
||||
override fun hashCode(): Int = owningKey.hashCode()
|
||||
abstract fun toAnonymous() : AnonymousParty
|
||||
|
||||
abstract fun ref(bytes: OpaqueBytes): PartyAndReference
|
||||
fun ref(vararg bytes: Byte) = ref(OpaqueBytes.of(*bytes))
|
||||
}
|
@ -8,18 +8,14 @@ import java.security.PublicKey
|
||||
* The [AnonymousParty] class contains enough information to uniquely identify a [Party] while excluding private
|
||||
* information such as name. It is intended to represent a party on the distributed ledger.
|
||||
*/
|
||||
open class AnonymousParty(val owningKey: CompositeKey) {
|
||||
class AnonymousParty(owningKey: CompositeKey) : AbstractParty(owningKey) {
|
||||
/** A helper constructor that converts the given [PublicKey] in to a [CompositeKey] with a single node */
|
||||
constructor(owningKey: PublicKey) : this(owningKey.composite)
|
||||
|
||||
/** 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()} <Anonymous>"
|
||||
|
||||
fun ref(bytes: OpaqueBytes) = PartyAndReference(this, bytes)
|
||||
fun ref(vararg bytes: Byte) = ref(OpaqueBytes.of(*bytes))
|
||||
override fun ref(bytes: OpaqueBytes): PartyAndReference = PartyAndReference(this, bytes)
|
||||
override fun toAnonymous() = this
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package net.corda.core.crypto
|
||||
|
||||
import net.corda.core.contracts.PartyAndReference
|
||||
import net.corda.core.serialization.OpaqueBytes
|
||||
import java.security.PublicKey
|
||||
|
||||
/**
|
||||
@ -9,7 +11,7 @@ import java.security.PublicKey
|
||||
* cryptographic public key primitives into a tree structure.
|
||||
*
|
||||
* For example: Alice has two key pairs (pub1/priv1 and pub2/priv2), and wants to be able to sign transactions with either of them.
|
||||
* Her advertised [Party] then has a legal [name] "Alice" and an [owingKey] "pub1 or pub2".
|
||||
* Her advertised [Party] then has a legal [name] "Alice" and an [owningKey] "pub1 or pub2".
|
||||
*
|
||||
* [Party] is also used for service identities. E.g. Alice may also be running an interest rate oracle on her Corda node,
|
||||
* which requires a separate signing key (and an identifying name). Services can also be distributed – run by a coordinated
|
||||
@ -20,9 +22,11 @@ import java.security.PublicKey
|
||||
*
|
||||
* @see CompositeKey
|
||||
*/
|
||||
class Party(val name: String, owningKey: CompositeKey) : AnonymousParty(owningKey) {
|
||||
class Party(val name: String, owningKey: CompositeKey) : AbstractParty(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 toAnonymous(): AnonymousParty = AnonymousParty(owningKey)
|
||||
override fun toString() = "${owningKey.toBase58String()} (${name})"
|
||||
|
||||
override fun ref(bytes: OpaqueBytes): PartyAndReference = PartyAndReference(this.toAnonymous(), bytes)
|
||||
}
|
@ -197,7 +197,7 @@ interface VaultService {
|
||||
fun generateSpend(tx: TransactionBuilder,
|
||||
amount: Amount<Currency>,
|
||||
to: CompositeKey,
|
||||
onlyFromParties: Set<AnonymousParty>? = null): Pair<TransactionBuilder, List<CompositeKey>>
|
||||
onlyFromParties: Set<AbstractParty>? = null): Pair<TransactionBuilder, List<CompositeKey>>
|
||||
|
||||
/**
|
||||
* Return [ContractState]s of a given [Contract] type and list of [Vault.StateStatus]
|
||||
@ -216,7 +216,7 @@ inline fun <reified T : LinearState> VaultService.linearHeadsOfType() =
|
||||
states(setOf(T::class.java), EnumSet.of(Vault.StateStatus.UNCONSUMED))
|
||||
.associateBy { it.state.data.linearId }.mapValues { it.value }
|
||||
|
||||
inline fun <reified T : DealState> VaultService.dealsWith(party: AnonymousParty) = linearHeadsOfType<T>().values.filter {
|
||||
inline fun <reified T : DealState> VaultService.dealsWith(party: AbstractParty) = linearHeadsOfType<T>().values.filter {
|
||||
it.state.data.parties.any { it == party }
|
||||
}
|
||||
|
||||
|
@ -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 == serviceHub.myInfo.legalIdentity }.owningKey))
|
||||
return Pair(ptx, arrayListOf(deal.parties.single { it == serviceHub.myInfo.legalIdentity as AbstractParty }.owningKey))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,9 +12,9 @@ class PartyTest {
|
||||
val differentKey = entropyToKeyPair(BigInteger.valueOf(7201702L)).public.composite
|
||||
val anonymousParty = AnonymousParty(key)
|
||||
val party = Party("test key", key)
|
||||
assertEquals(party, anonymousParty)
|
||||
assertEquals(anonymousParty, party)
|
||||
assertNotEquals(AnonymousParty(differentKey), anonymousParty)
|
||||
assertNotEquals(AnonymousParty(differentKey), party)
|
||||
assertEquals<AbstractParty>(party, anonymousParty)
|
||||
assertEquals<AbstractParty>(anonymousParty, party)
|
||||
assertNotEquals<AbstractParty>(AnonymousParty(differentKey), anonymousParty)
|
||||
assertNotEquals<AbstractParty>(AnonymousParty(differentKey), party)
|
||||
}
|
||||
}
|
@ -192,12 +192,12 @@ fun Iterable<ContractState>.sumCashOrZero(currency: Issued<Currency>): Amount<Is
|
||||
}
|
||||
|
||||
fun Cash.State.ownedBy(owner: CompositeKey) = copy(owner = owner)
|
||||
fun Cash.State.issuedBy(party: AnonymousParty) = copy(amount = Amount(amount.quantity, amount.token.copy(issuer = amount.token.issuer.copy(party = party.toAnonymous()))))
|
||||
fun Cash.State.issuedBy(party: AbstractParty) = copy(amount = Amount(amount.quantity, amount.token.copy(issuer = amount.token.issuer.copy(party = party.toAnonymous()))))
|
||||
fun Cash.State.issuedBy(deposit: PartyAndReference) = copy(amount = Amount(amount.quantity, amount.token.copy(issuer = deposit)))
|
||||
fun Cash.State.withDeposit(deposit: PartyAndReference): Cash.State = copy(amount = amount.copy(token = amount.token.copy(issuer = deposit)))
|
||||
|
||||
infix fun Cash.State.`owned by`(owner: CompositeKey) = ownedBy(owner)
|
||||
infix fun Cash.State.`issued by`(party: AnonymousParty) = issuedBy(party)
|
||||
infix fun Cash.State.`issued by`(party: AbstractParty) = issuedBy(party)
|
||||
infix fun Cash.State.`issued by`(deposit: PartyAndReference) = issuedBy(deposit)
|
||||
infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State = withDeposit(deposit)
|
||||
|
||||
|
@ -463,7 +463,7 @@ class Obligation<P> : Contract {
|
||||
* Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey.
|
||||
*/
|
||||
fun generateIssue(tx: TransactionBuilder,
|
||||
obligor: AnonymousParty,
|
||||
obligor: AbstractParty,
|
||||
issuanceDef: Terms<P>,
|
||||
pennies: Long,
|
||||
beneficiary: CompositeKey,
|
||||
@ -707,9 +707,9 @@ fun <P> Iterable<ContractState>.sumObligationsOrZero(issuanceDef: Issued<Obligat
|
||||
= filterIsInstance<Obligation.State<P>>().filter { it.lifecycle == Obligation.Lifecycle.NORMAL }.map { it.amount }.sumOrZero(issuanceDef)
|
||||
|
||||
infix fun <T> Obligation.State<T>.at(dueBefore: Instant) = copy(template = template.copy(dueBefore = dueBefore))
|
||||
infix fun <T> Obligation.State<T>.between(parties: Pair<AnonymousParty, CompositeKey>) = copy(obligor = parties.first.toAnonymous(), beneficiary = parties.second)
|
||||
infix fun <T> Obligation.State<T>.between(parties: Pair<AbstractParty, CompositeKey>) = copy(obligor = parties.first.toAnonymous(), beneficiary = parties.second)
|
||||
infix fun <T> Obligation.State<T>.`owned by`(owner: CompositeKey) = copy(beneficiary = owner)
|
||||
infix fun <T> Obligation.State<T>.`issued by`(party: AnonymousParty) = copy(obligor = party.toAnonymous())
|
||||
infix fun <T> Obligation.State<T>.`issued by`(party: AbstractParty) = copy(obligor = party.toAnonymous())
|
||||
// For Java users:
|
||||
@Suppress("unused") fun <T> Obligation.State<T>.ownedBy(owner: CompositeKey) = copy(beneficiary = owner)
|
||||
|
||||
|
@ -4,13 +4,14 @@ import net.corda.core.contracts.Contract
|
||||
import net.corda.core.contracts.DealState
|
||||
import net.corda.core.contracts.TransactionForContract
|
||||
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.crypto.SecureHash
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import java.security.PublicKey
|
||||
|
||||
class DummyDealContract: Contract {
|
||||
class DummyDealContract : Contract {
|
||||
override val legalContractReference: SecureHash = SecureHash.sha256("TestDeal")
|
||||
|
||||
override fun verify(tx: TransactionForContract) {}
|
||||
@ -20,10 +21,11 @@ class DummyDealContract: Contract {
|
||||
override val participants: List<CompositeKey> = listOf(),
|
||||
override val linearId: UniqueIdentifier = UniqueIdentifier(),
|
||||
override val ref: String,
|
||||
override val parties: List<Party> = listOf()) : DealState {
|
||||
override val parties: List<AnonymousParty> = listOf()) : DealState {
|
||||
override fun isRelevant(ourKeys: Set<PublicKey>): Boolean {
|
||||
return participants.any { it.containsAny(ourKeys) }
|
||||
}
|
||||
|
||||
override fun generateAgreement(notary: Party): TransactionBuilder {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ class CashTests {
|
||||
assertTrue(tx.inputs.isEmpty())
|
||||
val s = tx.outputs[0].data as Cash.State
|
||||
assertEquals(100.DOLLARS `issued by` MINI_CORP.ref(12, 34), s.amount)
|
||||
assertEquals(MINI_CORP, s.amount.token.issuer.party)
|
||||
assertEquals(MINI_CORP as AbstractParty, s.amount.token.issuer.party)
|
||||
assertEquals(DUMMY_PUBKEY_1, s.owner)
|
||||
assertTrue(tx.commands[0].value is Cash.Commands.Issue)
|
||||
assertEquals(MINI_CORP_PUBKEY, tx.commands[0].signers[0])
|
||||
|
@ -7,6 +7,7 @@ import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.ThreadBox
|
||||
import net.corda.core.bufferUntilSubscribed
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.AbstractParty
|
||||
import net.corda.core.crypto.AnonymousParty
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.SecureHash
|
||||
@ -222,7 +223,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
override fun generateSpend(tx: TransactionBuilder,
|
||||
amount: Amount<Currency>,
|
||||
to: CompositeKey,
|
||||
onlyFromParties: Set<AnonymousParty>?): Pair<TransactionBuilder, List<CompositeKey>> {
|
||||
onlyFromParties: Set<AbstractParty>?): Pair<TransactionBuilder, List<CompositeKey>> {
|
||||
// Discussion
|
||||
//
|
||||
// This code is analogous to the Wallet.send() set of methods in bitcoinj, and has the same general outline.
|
||||
|
@ -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.AnonymousParty
|
||||
import net.corda.core.crypto.AbstractParty
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.node.CordaPluginRegistry
|
||||
import net.corda.core.node.PluginServiceHub
|
||||
@ -78,7 +78,7 @@ object AutoOfferFlow {
|
||||
return stx
|
||||
}
|
||||
|
||||
private fun <T: AnonymousParty> notUs(parties: List<T>): List<T> {
|
||||
private fun <T: AbstractParty> notUs(parties: List<T>): List<T> {
|
||||
val notUsParties: MutableList<T> = arrayListOf()
|
||||
for (party in parties) {
|
||||
if (serviceHub.myInfo.legalIdentity != party) {
|
||||
|
@ -4,7 +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.AbstractParty
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.getOrThrow
|
||||
@ -34,7 +34,7 @@ class PortfolioApi(val rpc: CordaRPCOps) {
|
||||
private val ownParty: Party get() = rpc.nodeIdentity().legalIdentity
|
||||
private val portfolioUtils = PortfolioApiUtils(ownParty)
|
||||
|
||||
private inline fun <reified T : DealState> dealsWith(party: AnonymousParty): List<StateAndRef<T>> {
|
||||
private inline fun <reified T : DealState> dealsWith(party: AbstractParty): List<StateAndRef<T>> {
|
||||
return rpc.vaultAndUpdates().first.filterStatesOfType<T>().filter { it.state.data.parties.any { it == party } }
|
||||
}
|
||||
|
||||
@ -221,7 +221,7 @@ class PortfolioApi(val rpc: CordaRPCOps) {
|
||||
return withParty(partyName) { party ->
|
||||
withPortfolio(party) { state ->
|
||||
if (state.valuation != null) {
|
||||
val isValuer = state.valuer as AnonymousParty == ownParty
|
||||
val isValuer = state.valuer as AbstractParty == ownParty
|
||||
val rawMtm = state.valuation.presentValues.map {
|
||||
it.value.amounts.first().amount
|
||||
}.reduce { a, b -> a + b }
|
||||
|
@ -5,6 +5,7 @@ import com.opengamma.strata.product.swap.IborRateCalculation
|
||||
import com.opengamma.strata.product.swap.RateCalculationSwapLeg
|
||||
import com.opengamma.strata.product.swap.SwapLegType
|
||||
import net.corda.core.contracts.hash
|
||||
import net.corda.core.crypto.AbstractParty
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.vega.contracts.IRSState
|
||||
import net.corda.vega.contracts.PortfolioState
|
||||
@ -122,7 +123,7 @@ class PortfolioApiUtils(private val ownParty: Party) {
|
||||
val ref: String)
|
||||
|
||||
fun createTradeView(state: IRSState): TradeView {
|
||||
val trade = if (state.buyer == ownParty) state.swap.toFloatingLeg() else state.swap.toFloatingLeg()
|
||||
val trade = if (state.buyer == ownParty as AbstractParty) 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
|
||||
|
@ -9,7 +9,7 @@ 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.AbstractParty
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import java.math.BigDecimal
|
||||
@ -48,7 +48,7 @@ data class SwapData(
|
||||
val notional: BigDecimal,
|
||||
val fixedRate: BigDecimal) {
|
||||
|
||||
fun getLegForParty(party: AnonymousParty): Leg {
|
||||
fun getLegForParty(party: AbstractParty): Leg {
|
||||
return if (party == buyer.second) FixedLeg(notional) else FloatingLeg(notional)
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.Issued
|
||||
import net.corda.core.contracts.PartyAndReference
|
||||
import net.corda.core.contracts.withoutIssuer
|
||||
import net.corda.core.crypto.AbstractParty
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.flows.FlowException
|
||||
import net.corda.core.getOrThrow
|
||||
@ -199,7 +200,7 @@ class NewTransaction : Fragment() {
|
||||
)
|
||||
availableAmount.textProperty()
|
||||
.bind(Bindings.createStringBinding({
|
||||
val filteredCash = cash.filtered { it.token.issuer.party == issuer.value && it.token.product == currencyChoiceBox.value }
|
||||
val filteredCash = cash.filtered { it.token.issuer.party as AbstractParty == issuer.value && it.token.product == currencyChoiceBox.value }
|
||||
.map { it.withoutIssuer().quantity }
|
||||
"${filteredCash.sum()} ${currencyChoiceBox.value?.currencyCode} Available"
|
||||
}, arrayOf(currencyChoiceBox.valueProperty(), issuerChoiceBox.valueProperty())))
|
||||
|
@ -6,6 +6,7 @@ import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.contracts.Issued
|
||||
import net.corda.core.contracts.PartyAndReference
|
||||
import net.corda.core.contracts.USD
|
||||
import net.corda.core.crypto.AbstractParty
|
||||
import net.corda.core.crypto.AnonymousParty
|
||||
import net.corda.core.flows.FlowException
|
||||
import net.corda.core.getOrThrow
|
||||
@ -50,7 +51,7 @@ data class CrossCashCommand(
|
||||
* Map from node to (map from issuer to USD quantity)
|
||||
*/
|
||||
data class CrossCashState(
|
||||
val nodeVaults: Map<AnonymousParty, Map<AnonymousParty, Long>>,
|
||||
val nodeVaults: Map<AbstractParty, Map<AbstractParty, Long>>,
|
||||
|
||||
// node -> (notifying node -> [(issuer, amount)])
|
||||
// This map holds the queues that encode the non-determinism of how tx notifications arrive in the background.
|
||||
@ -68,20 +69,20 @@ data class CrossCashState(
|
||||
// requires more concurrent code which is conceptually also more complex than the current design.
|
||||
// TODO: Alternative: We may possibly reduce the complexity of the search even further using some form of
|
||||
// knapsack instead of the naive search
|
||||
val diffQueues: Map<AnonymousParty, Map<AnonymousParty, List<Pair<AnonymousParty, Long>>>>
|
||||
val diffQueues: Map<AbstractParty, Map<AbstractParty, List<Pair<AbstractParty, Long>>>>
|
||||
) {
|
||||
fun copyVaults(): HashMap<AnonymousParty, HashMap<AnonymousParty, Long>> {
|
||||
val newNodeVaults = HashMap<AnonymousParty, HashMap<AnonymousParty, Long>>()
|
||||
fun copyVaults(): HashMap<AbstractParty, HashMap<AbstractParty, Long>> {
|
||||
val newNodeVaults = HashMap<AbstractParty, HashMap<AbstractParty, Long>>()
|
||||
for ((key, value) in nodeVaults) {
|
||||
newNodeVaults[key] = HashMap(value)
|
||||
}
|
||||
return newNodeVaults
|
||||
}
|
||||
|
||||
fun copyQueues(): HashMap<AnonymousParty, HashMap<AnonymousParty, ArrayList<Pair<AnonymousParty, Long>>>> {
|
||||
val newDiffQueues = HashMap<AnonymousParty, HashMap<AnonymousParty, ArrayList<Pair<AnonymousParty, Long>>>>()
|
||||
fun copyQueues(): HashMap<AbstractParty, HashMap<AbstractParty, ArrayList<Pair<AbstractParty, Long>>>> {
|
||||
val newDiffQueues = HashMap<AbstractParty, HashMap<AbstractParty, ArrayList<Pair<AbstractParty, Long>>>>()
|
||||
for ((node, queues) in diffQueues) {
|
||||
val newQueues = HashMap<AnonymousParty, ArrayList<Pair<AnonymousParty, Long>>>()
|
||||
val newQueues = HashMap<AbstractParty, ArrayList<Pair<AbstractParty, Long>>>()
|
||||
for ((sender, value) in queues) {
|
||||
newQueues[sender] = ArrayList(value)
|
||||
}
|
||||
@ -217,9 +218,9 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
|
||||
|
||||
gatherRemoteState = { previousState ->
|
||||
log.info("Reifying state...")
|
||||
val currentNodeVaults = HashMap<AnonymousParty, HashMap<AnonymousParty, Long>>()
|
||||
val currentNodeVaults = HashMap<AbstractParty, HashMap<AbstractParty, Long>>()
|
||||
simpleNodes.forEach {
|
||||
val quantities = HashMap<AnonymousParty, Long>()
|
||||
val quantities = HashMap<AbstractParty, Long>()
|
||||
val vault = it.connection.proxy.vaultAndUpdates().first
|
||||
vault.forEach {
|
||||
val state = it.state.data
|
||||
@ -231,7 +232,7 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
|
||||
currentNodeVaults.put(it.info.legalIdentity, quantities)
|
||||
}
|
||||
val (consistentVaults, diffQueues) = if (previousState == null) {
|
||||
Pair(currentNodeVaults, mapOf<AnonymousParty, Map<AnonymousParty, List<Pair<AnonymousParty, Long>>>>())
|
||||
Pair(currentNodeVaults, mapOf<AbstractParty, Map<AbstractParty, List<Pair<AbstractParty, Long>>>>())
|
||||
} else {
|
||||
log.info("${previousState.diffQueues.values.sumBy { it.values.sumBy { it.size } }} txs in limbo")
|
||||
val newDiffQueues = previousState.copyQueues()
|
||||
@ -249,12 +250,12 @@ val crossCashTest = LoadTest<CrossCashCommand, CrossCashState>(
|
||||
"\nActual gathered state:\n${CrossCashState(currentNodeVaults, mapOf())}"
|
||||
)
|
||||
// TODO We should terminate here with an exception, we cannot carry on as we have an inconsistent model. We carry on currently because we always diverge due to notarisation failures
|
||||
return@LoadTest CrossCashState(currentNodeVaults, mapOf<AnonymousParty, Map<AnonymousParty, List<Pair<AnonymousParty, Long>>>>())
|
||||
return@LoadTest CrossCashState(currentNodeVaults, mapOf<AbstractParty, Map<AbstractParty, List<Pair<AbstractParty, Long>>>>())
|
||||
}
|
||||
if (matches.size > 1) {
|
||||
log.warn("Multiple predicted states match the remote state")
|
||||
}
|
||||
val minimumMatches = matches.fold<Map<AnonymousParty, Int>, HashMap<AnonymousParty, Int>?>(null) { minimum, next ->
|
||||
val minimumMatches = matches.fold<Map<AbstractParty, Int>, HashMap<AbstractParty, Int>?>(null) { minimum, next ->
|
||||
if (minimum == null) {
|
||||
HashMap(next)
|
||||
} else {
|
||||
|
@ -6,7 +6,7 @@ import net.corda.client.mock.pickOne
|
||||
import net.corda.client.mock.replicatePoisson
|
||||
import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.contracts.USD
|
||||
import net.corda.core.crypto.AnonymousParty
|
||||
import net.corda.core.crypto.AbstractParty
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.flows.FlowException
|
||||
import net.corda.core.getOrThrow
|
||||
@ -28,9 +28,9 @@ data class SelfIssueCommand(
|
||||
)
|
||||
|
||||
data class SelfIssueState(
|
||||
val vaultsSelfIssued: Map<AnonymousParty, Long>
|
||||
val vaultsSelfIssued: Map<AbstractParty, Long>
|
||||
) {
|
||||
fun copyVaults(): HashMap<AnonymousParty, Long> {
|
||||
fun copyVaults(): HashMap<AbstractParty, Long> {
|
||||
return HashMap(vaultsSelfIssued)
|
||||
}
|
||||
}
|
||||
@ -72,14 +72,14 @@ val selfIssueTest = LoadTest<SelfIssueCommand, SelfIssueState>(
|
||||
},
|
||||
|
||||
gatherRemoteState = { previousState ->
|
||||
val selfIssueVaults = HashMap<AnonymousParty, Long>()
|
||||
val selfIssueVaults = HashMap<AbstractParty, Long>()
|
||||
simpleNodes.forEach { node ->
|
||||
val vault = node.connection.proxy.vaultAndUpdates().first
|
||||
vault.forEach {
|
||||
val state = it.state.data
|
||||
if (state is Cash.State) {
|
||||
val issuer = state.amount.token.issuer.party
|
||||
if (issuer == node.info.legalIdentity as AnonymousParty) {
|
||||
if (issuer == node.info.legalIdentity as AbstractParty) {
|
||||
selfIssueVaults.put(issuer, (selfIssueVaults[issuer] ?: 0L) + state.amount.quantity)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user