Replaces keys and parties in states with AbstractParty

Switch to using AbstractParty as the standard identifier for parties in
states, so that full parties can be used during construction of
transactions and anonymised parties when the transaction is being added
to the ledger.
This commit is contained in:
Ross Nicoll
2017-05-11 11:25:00 +01:00
parent d3bb040355
commit c13a99a2f9
110 changed files with 786 additions and 720 deletions

View File

@ -57,7 +57,7 @@ class BFTNotaryServiceTests : NodeBasedTest() {
firstSpend.resultFuture.getOrThrow()
val secondSpendTx = TransactionType.General.Builder(notaryParty).withItems(inputState).run {
val dummyState = DummyContract.SingleOwnerState(0, alice.info.legalIdentity.owningKey)
val dummyState = DummyContract.SingleOwnerState(0, alice.info.legalIdentity)
addOutputState(dummyState)
signWith(aliceKey)
toSignedTransaction(false)

View File

@ -46,7 +46,7 @@ class RaftNotaryServiceTests : NodeBasedTest() {
firstSpend.resultFuture.getOrThrow()
val secondSpendTx = TransactionType.General.Builder(notaryParty).withItems(inputState).run {
val dummyState = DummyContract.SingleOwnerState(0, alice.info.legalIdentity.owningKey)
val dummyState = DummyContract.SingleOwnerState(0, alice.info.legalIdentity)
addOutputState(dummyState)
signWith(aliceKey)
toSignedTransaction(false)

View File

@ -115,7 +115,7 @@ class ContractUpgradeHandler(otherSide: Party) : AbstractStateReplacementFlow.Ac
val proposedTx = proposal.stx.tx
val expectedTx = ContractUpgradeFlow.assembleBareTx(oldStateAndRef, proposal.modification).toWireTransaction()
requireThat {
"The instigator is one of the participants" using (otherSide.owningKey in oldStateAndRef.state.data.participants)
"The instigator is one of the participants" using (otherSide in oldStateAndRef.state.data.participants)
"The proposed upgrade ${proposal.modification.javaClass} is a trusted upgrade path" using (proposal.modification == authorisedUpgrade)
"The proposed tx matches the expected tx for this upgrade" using (proposedTx == expectedTx)
}

View File

@ -3,6 +3,7 @@ package net.corda.node.services.identity
import net.corda.core.contracts.PartyAndReference
import net.corda.core.contracts.requireThat
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party
import net.corda.core.node.services.IdentityService
@ -16,7 +17,6 @@ import java.security.cert.*
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import javax.annotation.concurrent.ThreadSafe
import javax.security.auth.x500.X500Principal
/**
* Simple identity service which caches parties and provides functionality for efficient lookup.
@ -44,7 +44,7 @@ class InMemoryIdentityService : SingletonSerializeAsToken(), IdentityService {
@Deprecated("Use partyFromX500Name")
override fun partyFromName(name: String): Party? = principalToParties[X500Name(name)]
override fun partyFromX500Name(principal: X500Name): Party? = principalToParties[principal]
override fun partyFromAnonymous(party: AnonymousParty): Party? = partyFromKey(party.owningKey)
override fun partyFromAnonymous(party: AbstractParty): Party? = partyFromKey(party.owningKey)
override fun partyFromAnonymous(partyRef: PartyAndReference) = partyFromAnonymous(partyRef.party)
@Throws(IdentityService.UnknownAnonymousPartyException::class)

View File

@ -11,11 +11,12 @@ import io.requery.kotlin.notNull
import io.requery.query.RowExpression
import net.corda.contracts.asset.Cash
import net.corda.contracts.asset.OnLedgerAsset
import net.corda.contracts.clause.AbstractConserveAmount
import net.corda.core.ThreadBox
import net.corda.core.bufferUntilSubscribed
import net.corda.core.contracts.*
import net.corda.core.crypto.*
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.containsAny
import net.corda.core.crypto.toBase58String
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub
@ -468,7 +469,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
@Suspendable
override fun generateSpend(tx: TransactionBuilder,
amount: Amount<Currency>,
to: PublicKey,
to: AbstractParty,
onlyFromParties: Set<AbstractParty>?): Pair<TransactionBuilder, List<PublicKey>> {
// Retrieve unspent and unlocked cash states that meet our spending criteria.
val acceptableCoins = unconsumedStatesForSpending<Cash.State>(amount, onlyFromParties, tx.notary, tx.lockId)
@ -477,7 +478,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
{ Cash().generateMoveCommand() })
}
private fun deriveState(txState: TransactionState<Cash.State>, amount: Amount<Issued<Currency>>, owner: PublicKey)
private fun deriveState(txState: TransactionState<Cash.State>, amount: Amount<Issued<Currency>>, owner: AbstractParty)
= txState.copy(data = txState.data.copy(amount = amount, owner = owner))
private fun makeUpdate(tx: WireTransaction, ourKeys: Set<PublicKey>): Vault.Update {
@ -528,7 +529,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
}
private fun isRelevant(state: ContractState, ourKeys: Set<PublicKey>) = when (state) {
is OwnableState -> state.owner.containsAny(ourKeys)
is OwnableState -> state.owner.owningKey.containsAny(ourKeys)
// It's potentially of interest to the vault
is LinearState -> state.isRelevant(ourKeys)
else -> false

View File

@ -91,7 +91,7 @@ class CordaRPCOpsImplTest {
val expectedState = Cash.State(Amount(quantity,
Issued(aliceNode.info.legalIdentity.ref(ref), GBP)),
recipient.owningKey)
recipient)
var issueSmId: StateMachineRunId? = null
stateMachineUpdates.expectEvents {

View File

@ -14,6 +14,7 @@ import net.corda.core.flows.FlowStateMachine
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.StateMachineRunId
import net.corda.core.getOrThrow
import net.corda.core.identity.AbstractParty
import net.corda.core.map
import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.NodeInfo
@ -97,7 +98,7 @@ class TwoPartyTradeFlowTests {
}
val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
fillUpForSeller(false, aliceNode.info.legalIdentity,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second
}
@ -144,7 +145,7 @@ class TwoPartyTradeFlowTests {
}
val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
fillUpForSeller(false, aliceNode.info.legalIdentity,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second
}
@ -195,7 +196,7 @@ class TwoPartyTradeFlowTests {
bobNode.services.fillWithSomeTestCash(2000.DOLLARS, outputNotary = notaryNode.info.notaryIdentity)
}
val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
fillUpForSeller(false, aliceNode.info.legalIdentity,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second
}
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey, notaryKey)
@ -301,6 +302,7 @@ class TwoPartyTradeFlowTests {
val notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name)
val aliceNode = makeNodeWithTracking(notaryNode.info.address, ALICE.name)
val bobNode = makeNodeWithTracking(notaryNode.info.address, BOB.name)
val alice = aliceNode.info.legalIdentity
val aliceKey = aliceNode.services.legalIdentityKey
ledger(aliceNode.services) {
@ -317,12 +319,13 @@ class TwoPartyTradeFlowTests {
}
val extraKey = bobNode.keyManagement.freshKey()
val bobsFakeCash = fillUpForBuyer(false, extraKey.public,
val extraPublicKey = extraKey.public
val bobsFakeCash = fillUpForBuyer(false, AnonymousParty(extraPublicKey),
DUMMY_CASH_ISSUER.party,
notaryNode.info.notaryIdentity).second
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bobNode.services.legalIdentityKey, extraKey)
val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
fillUpForSeller(false, alice,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second
}
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey)
@ -416,13 +419,14 @@ class TwoPartyTradeFlowTests {
attachment(ByteArrayInputStream(stream.toByteArray()))
}
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public,
val bobsKey = bobNode.keyManagement.freshKey().public
val bobsFakeCash = fillUpForBuyer(false, AnonymousParty(bobsKey),
DUMMY_CASH_ISSUER.party,
notaryNode.info.notaryIdentity).second
insertFakeTransactions(bobsFakeCash, bobNode, notaryNode)
val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
fillUpForSeller(false, aliceNode.info.legalIdentity,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second
}
@ -520,14 +524,16 @@ class TwoPartyTradeFlowTests {
val notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name)
val aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name)
val bobNode = net.createPartyNode(notaryNode.info.address, BOB.name)
val alice = aliceNode.info.legalIdentity
val aliceKey = aliceNode.services.legalIdentityKey
val bob = bobNode.info.legalIdentity
val bobKey = bobNode.services.legalIdentityKey
val issuer = MEGA_CORP.ref(1, 2, 3)
val bobsBadCash = fillUpForBuyer(bobError, bobKey.public, DUMMY_CASH_ISSUER.party,
val bobsBadCash = fillUpForBuyer(bobError, bob, DUMMY_CASH_ISSUER.party,
notaryNode.info.notaryIdentity).second
val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(aliceError, aliceNode.info.legalIdentity.owningKey,
fillUpForSeller(aliceError, alice,
1200.DOLLARS `issued by` issuer, null, notaryNode.info.notaryIdentity).second
}
@ -571,16 +577,16 @@ class TwoPartyTradeFlowTests {
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForBuyer(
withError: Boolean,
owner: PublicKey,
issuer: AnonymousParty,
owner: AbstractParty,
issuer: AbstractParty,
notary: Party): Pair<Vault<ContractState>, List<WireTransaction>> {
val interimOwnerKey = MEGA_CORP_PUBKEY
val interimOwner = MEGA_CORP
// Bob (Buyer) has some cash he got from the Bank of Elbonia, Alice (Seller) has some commercial paper she
// wants to sell to Bob.
val eb1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
// Issued money to itself.
output("elbonian money 1", notary = notary) { 800.DOLLARS.CASH `issued by` issuer `owned by` interimOwnerKey }
output("elbonian money 2", notary = notary) { 1000.DOLLARS.CASH `issued by` issuer `owned by` interimOwnerKey }
output("elbonian money 1", notary = notary) { 800.DOLLARS.CASH `issued by` issuer `owned by` interimOwner }
output("elbonian money 2", notary = notary) { 1000.DOLLARS.CASH `issued by` issuer `owned by` interimOwner }
if (!withError) {
command(issuer.owningKey) { Cash.Commands.Issue() }
} else {
@ -599,15 +605,15 @@ class TwoPartyTradeFlowTests {
val bc1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
input("elbonian money 1")
output("bob cash 1", notary = notary) { 800.DOLLARS.CASH `issued by` issuer `owned by` owner }
command(interimOwnerKey) { Cash.Commands.Move() }
command(interimOwner.owningKey) { Cash.Commands.Move() }
this.verifies()
}
val bc2 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
input("elbonian money 2")
output("bob cash 2", notary = notary) { 300.DOLLARS.CASH `issued by` issuer `owned by` owner }
output(notary = notary) { 700.DOLLARS.CASH `issued by` issuer `owned by` interimOwnerKey } // Change output.
command(interimOwnerKey) { Cash.Commands.Move() }
output(notary = notary) { 700.DOLLARS.CASH `issued by` issuer `owned by` interimOwner } // Change output.
command(interimOwner.owningKey) { Cash.Commands.Move() }
this.verifies()
}
@ -617,7 +623,7 @@ class TwoPartyTradeFlowTests {
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForSeller(
withError: Boolean,
owner: PublicKey,
owner: AbstractParty,
amount: Amount<Issued<Currency>>,
attachmentID: SecureHash?,
notary: Party): Pair<Vault<ContractState>, List<WireTransaction>> {

View File

@ -123,9 +123,9 @@ class NotaryChangeTests {
val owner = node.info.legalIdentity.ref(0)
val notary = notaryNode.info.notaryIdentity
val stateA = DummyContract.SingleOwnerState(Random().nextInt(), owner.party.owningKey)
val stateB = DummyContract.SingleOwnerState(Random().nextInt(), owner.party.owningKey)
val stateC = DummyContract.SingleOwnerState(Random().nextInt(), owner.party.owningKey)
val stateA = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
val stateB = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
val stateC = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
val tx = TransactionType.General.Builder(null).apply {
addCommand(Command(DummyContract.Commands.Create(), owner.party.owningKey))
@ -162,7 +162,7 @@ fun issueState(node: AbstractNode, notaryNode: AbstractNode): StateAndRef<*> {
fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode, notaryNode: AbstractNode): StateAndRef<DummyContract.MultiOwnerState> {
val state = TransactionState(DummyContract.MultiOwnerState(0,
listOf(nodeA.info.legalIdentity.owningKey, nodeB.info.legalIdentity.owningKey)), notaryNode.info.notaryIdentity)
listOf(nodeA.info.legalIdentity, nodeB.info.legalIdentity)), notaryNode.info.notaryIdentity)
val tx = TransactionType.NotaryChange.Builder(notaryNode.info.notaryIdentity).withItems(state)
val nodeAKey = nodeA.services.legalIdentityKey
val nodeBKey = nodeB.services.legalIdentityKey

View File

@ -10,6 +10,7 @@ import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.NullPublicKey
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.toBase58String
import net.corda.core.identity.AnonymousParty
import net.corda.core.node.services.Vault
import net.corda.core.serialization.serialize
import net.corda.core.serialization.storageKryo
@ -129,7 +130,7 @@ class RequeryConfigurationTest {
index = txnState.index
stateStatus = Vault.StateStatus.UNCONSUMED
contractStateClassName = DummyContract.SingleOwnerState::class.java.name
contractState = DummyContract.SingleOwnerState(owner = DUMMY_PUBKEY_1).serialize(storageKryo()).bytes
contractState = DummyContract.SingleOwnerState(owner = AnonymousParty(DUMMY_PUBKEY_1)).serialize(storageKryo()).bytes
notaryName = txn.tx.notary!!.name.toString()
notaryKey = txn.tx.notary!!.owningKey.toBase58String()
recordedTime = Instant.now()

View File

@ -5,6 +5,7 @@ import net.corda.core.days
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowLogicRef
import net.corda.core.flows.FlowLogicRefFactory
import net.corda.core.identity.AbstractParty
import net.corda.core.node.ServiceHub
import net.corda.core.node.services.VaultService
import net.corda.core.serialization.SingletonSerializeAsToken
@ -113,7 +114,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
}
class TestState(val flowLogicRef: FlowLogicRef, val instant: Instant) : LinearState, SchedulableState {
override val participants: List<PublicKey>
override val participants: List<AbstractParty>
get() = throw UnsupportedOperationException()
override val linearId = UniqueIdentifier()

View File

@ -2,12 +2,13 @@ package net.corda.node.services.events
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.*
import net.corda.core.identity.Party
import net.corda.core.crypto.containsAny
import net.corda.core.flows.FlowInitiator
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowLogicRefFactory
import net.corda.core.flows.SchedulableFlow
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.linearHeadsOfType
import net.corda.core.utilities.DUMMY_NOTARY
@ -46,10 +47,10 @@ class ScheduledFlowTests {
}
}
override val participants: List<PublicKey> = listOf(source.owningKey, destination.owningKey)
override val participants: List<AbstractParty> = listOf(source, destination)
override fun isRelevant(ourKeys: Set<PublicKey>): Boolean {
return participants.any { it.containsAny(ourKeys) }
return participants.any { it.owningKey.containsAny(ourKeys) }
}
}

View File

@ -37,7 +37,7 @@ class DataVendingServiceTests {
@Test
fun `notify of transaction`() {
val (vaultServiceNode, registerNode) = network.createTwoNodes()
val beneficiary = vaultServiceNode.info.legalIdentity.owningKey
val beneficiary = vaultServiceNode.info.legalIdentity
val deposit = registerNode.info.legalIdentity.ref(1)
network.runNetwork()
@ -67,7 +67,7 @@ class DataVendingServiceTests {
@Test
fun `notify failure`() {
val (vaultServiceNode, registerNode) = network.createTwoNodes()
val beneficiary = vaultServiceNode.info.legalIdentity.owningKey
val beneficiary = vaultServiceNode.info.legalIdentity
val deposit = MEGA_CORP.ref(1)
network.runNetwork()

View File

@ -6,6 +6,7 @@ import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TransactionState
import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.SecureHash
import net.corda.core.identity.AbstractParty
import net.corda.core.node.services.Vault
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
@ -86,7 +87,7 @@ class HibernateObserverTests {
override val contract: Contract
get() = throw UnsupportedOperationException()
override val participants: List<CompositeKey>
override val participants: List<AbstractParty>
get() = throw UnsupportedOperationException()
}

View File

@ -4,6 +4,7 @@ import net.corda.contracts.asset.Cash
import net.corda.contracts.asset.DUMMY_CASH_ISSUER
import net.corda.contracts.testing.fillWithSomeTestCash
import net.corda.core.contracts.*
import net.corda.core.identity.AnonymousParty
import net.corda.core.node.services.StatesNotAvailableException
import net.corda.core.node.services.TxWritableStorageService
import net.corda.core.node.services.VaultService
@ -401,11 +402,11 @@ class NodeVaultServiceTest {
fun addNoteToTransaction() {
database.transaction {
val freshKey = services.legalIdentityKey
val freshKey = services.legalIdentityKey.public
// Issue a txn to Send us some Money
val usefulTX = TransactionType.General.Builder(null).apply {
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public, DUMMY_NOTARY)
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshKey), DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
}.toSignedTransaction()
@ -418,7 +419,7 @@ class NodeVaultServiceTest {
// Issue more Money (GBP)
val anotherTX = TransactionType.General.Builder(null).apply {
Cash().generateIssue(this, 200.POUNDS `issued by` MEGA_CORP.ref(1), freshKey.public, DUMMY_NOTARY)
Cash().generateIssue(this, 200.POUNDS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshKey), DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
}.toSignedTransaction()

View File

@ -206,9 +206,9 @@ class VaultQueryTests {
fun `unconsumed states by participants`() {
database.transaction {
services.fillWithSomeTestLinearStates(2, UniqueIdentifier("TEST"), participants = listOf(MEGA_CORP_PUBKEY, MINI_CORP_PUBKEY))
services.fillWithSomeTestDeals(listOf("456"), 3, participants = listOf(MEGA_CORP_PUBKEY, BIG_CORP_PUBKEY))
services.fillWithSomeTestDeals(listOf("123", "789"), participants = listOf(BIG_CORP_PUBKEY, MINI_CORP_PUBKEY))
services.fillWithSomeTestLinearStates(2, UniqueIdentifier("TEST"), participants = listOf(MEGA_CORP, MINI_CORP))
services.fillWithSomeTestDeals(listOf("456"), 3, participants = listOf(MEGA_CORP, BIG_CORP))
services.fillWithSomeTestDeals(listOf("123", "789"), participants = listOf(BIG_CORP, MINI_CORP))
// DOCSTART VaultQueryExample5
val criteria = VaultQueryCriteria(participantIdentities = listOf(MEGA_CORP.name, MINI_CORP.name))

View File

@ -4,17 +4,17 @@ import net.corda.contracts.asset.Cash
import net.corda.contracts.asset.DUMMY_CASH_ISSUER
import net.corda.contracts.testing.*
import net.corda.core.contracts.*
import net.corda.core.identity.AnonymousParty
import net.corda.core.node.services.VaultService
import net.corda.core.node.services.consumedStates
import net.corda.core.node.services.unconsumedStates
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.BOB_KEY
import net.corda.core.utilities.BOB
import net.corda.core.utilities.DUMMY_NOTARY
import net.corda.core.utilities.DUMMY_NOTARY_KEY
import net.corda.core.utilities.LogHelper
import net.corda.node.utilities.configureDatabase
import net.corda.node.utilities.transaction
import net.corda.testing.BOB_PUBKEY
import net.corda.testing.MEGA_CORP
import net.corda.testing.MEGA_CORP_KEY
import net.corda.testing.node.MockServices
@ -79,7 +79,7 @@ class VaultWithCashTest {
val state = w[0].state.data
assertEquals(30.45.DOLLARS `issued by` DUMMY_CASH_ISSUER, state.amount)
assertEquals(services.key.public, state.owner)
assertEquals(services.key.public, state.owner.owningKey)
assertEquals(34.70.DOLLARS `issued by` DUMMY_CASH_ISSUER, (w[2].state.data).amount)
assertEquals(34.85.DOLLARS `issued by` DUMMY_CASH_ISSUER, (w[1].state.data).amount)
@ -91,8 +91,9 @@ class VaultWithCashTest {
database.transaction {
// A tx that sends us money.
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
val usefulTX = TransactionType.General.Builder(null).apply {
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public, DUMMY_NOTARY)
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshPublicKey), DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
}.toSignedTransaction()
@ -101,7 +102,7 @@ class VaultWithCashTest {
// A tx that spends our money.
val spendTX = TransactionType.General.Builder(DUMMY_NOTARY).apply {
vault.generateSpend(this, 80.DOLLARS, BOB_PUBKEY)
vault.generateSpend(this, 80.DOLLARS, BOB)
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -110,7 +111,7 @@ class VaultWithCashTest {
// A tx that doesn't send us anything.
val irrelevantTX = TransactionType.General.Builder(DUMMY_NOTARY).apply {
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), BOB_KEY.public, DUMMY_NOTARY)
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), BOB, DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -128,13 +129,14 @@ class VaultWithCashTest {
@Test
fun `issue and attempt double spend`() {
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
database.transaction {
// A tx that sends us money.
services.fillWithSomeTestCash(100.DOLLARS, DUMMY_NOTARY, 10, 10, Random(0L),
issuedBy = MEGA_CORP.ref(1),
issuerKey = MEGA_CORP_KEY,
ownedBy = freshKey.public)
ownedBy = AnonymousParty(freshPublicKey))
println("Cash balance: ${vault.cashBalances[USD]}")
assertThat(vault.unconsumedStates<Cash.State>()).hasSize(10)
@ -149,7 +151,7 @@ class VaultWithCashTest {
try {
val txn1 =
TransactionType.General.Builder(DUMMY_NOTARY).apply {
vault.generateSpend(this, 60.DOLLARS, BOB_PUBKEY)
vault.generateSpend(this, 60.DOLLARS, BOB)
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -181,7 +183,7 @@ class VaultWithCashTest {
try {
val txn2 =
TransactionType.General.Builder(DUMMY_NOTARY).apply {
vault.generateSpend(this, 80.DOLLARS, BOB_PUBKEY)
vault.generateSpend(this, 80.DOLLARS, BOB)
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -219,12 +221,14 @@ class VaultWithCashTest {
fun `branching LinearStates fails to verify`() {
database.transaction {
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
val freshIdentity = AnonymousParty(freshPublicKey)
val linearId = UniqueIdentifier()
// Issue a linear state
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public)))
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public)))
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -239,12 +243,14 @@ class VaultWithCashTest {
fun `sequencing LinearStates works`() {
database.transaction {
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
val freshIdentity = AnonymousParty(freshPublicKey)
val linearId = UniqueIdentifier()
// Issue a linear state
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public)))
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -256,7 +262,7 @@ class VaultWithCashTest {
// Move the same state
val dummyMove = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public)))
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
addInputState(dummyIssue.tx.outRef<LinearState>(0))
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -272,8 +278,9 @@ class VaultWithCashTest {
fun `spending cash in vault of mixed state types works`() {
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, DUMMY_NOTARY, 3, 3, Random(0L), ownedBy = freshKey.public)
services.fillWithSomeTestCash(100.DOLLARS, DUMMY_NOTARY, 3, 3, Random(0L), ownedBy = AnonymousParty(freshPublicKey))
services.fillWithSomeTestCash(100.SWISS_FRANCS, DUMMY_NOTARY, 2, 2, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, DUMMY_NOTARY, 1, 1, Random(0L))
val cash = vault.unconsumedStates<Cash.State>()
@ -287,7 +294,7 @@ class VaultWithCashTest {
database.transaction {
// A tx that spends our money.
val spendTX = TransactionType.General.Builder(DUMMY_NOTARY).apply {
vault.generateSpend(this, 80.DOLLARS, BOB_PUBKEY)
vault.generateSpend(this, 80.DOLLARS, BOB)
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -305,6 +312,8 @@ class VaultWithCashTest {
fun `consuming multiple contract state types in same transaction`() {
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
val freshIdentity = AnonymousParty(freshPublicKey)
database.transaction {
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
@ -317,8 +326,8 @@ class VaultWithCashTest {
// Create a txn consuming different contract types
val dummyMove = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(DummyLinearContract.State(participants = listOf(freshKey.public)))
addOutputState(DummyDealContract.State(ref = "999", participants = listOf(freshKey.public)))
addOutputState(DummyLinearContract.State(participants = listOf(freshIdentity)))
addOutputState(DummyDealContract.State(ref = "999", participants = listOf(freshIdentity)))
addInputState(linearStates.first())
addInputState(deals.first())
signWith(DUMMY_NOTARY_KEY)