NodeInfo remove main identity (#1284)

* Remove node's main identitiy from NodeInfo.

Preparation for getting rid of services + supporting multiple identities
on the node.
NodeInfo keeps multiple identities as a list. For now the first one is treated as a special one.
Introduced function chooseIdentity in CoreTestUtils as a preparation for proper handling of multiple identities in the future.
Remove legalIdentityKey from ServiceHub, add extension function - chooseIdentity on ServiceHub.
Add `me` field on FlowStateMachineImplemetation, flows should know what the calling identity is.
Remove SERVICES_PREFIX in artemis messaging layer.

* Address minor comments.

* Fixes after rebase.

Remove chooseIdentity from ServiceHub

* Rename me to ourIdentity on FlowLogic

* Fixes after rebase

* Address Ross comments, fixes

* Fix after rebase

* Fix services certificate paths

Apply Patrick's patch.
This commit is contained in:
Katarzyna Streich
2017-09-15 14:39:34 +01:00
committed by josecoll
parent d747f71fe5
commit 495e870b74
144 changed files with 804 additions and 692 deletions

View File

@ -67,7 +67,7 @@ class IntegrationTestingTutorial {
(1..10).map { i ->
aliceProxy.startFlow(::CashPaymentFlow,
i.DOLLARS,
bob.nodeInfo.legalIdentity,
bob.nodeInfo.chooseIdentity(),
true
).returnValue
}.transpose().getOrThrow()
@ -89,7 +89,7 @@ class IntegrationTestingTutorial {
// START 5
for (i in 1..10) {
bobProxy.startFlow(::CashPaymentFlow, i.DOLLARS, alice.nodeInfo.legalIdentity).returnValue.getOrThrow()
bobProxy.startFlow(::CashPaymentFlow, i.DOLLARS, alice.nodeInfo.chooseIdentity()).returnValue.getOrThrow()
}
aliceVaultUpdates.expectEvents {

View File

@ -134,15 +134,14 @@ public class FlowCookbookJava {
// We may also need to identify a specific counterparty.
// Again, we do so using the network map.
// DOCSTART 2
Party namedCounterparty = getServiceHub().getNetworkMapCache().getNodeByLegalName(new CordaX500Name("NodeA", "London", "UK")).getLegalIdentity();
Party keyedCounterparty = getServiceHub().getNetworkMapCache().getNodeByLegalIdentityKey(dummyPubKey).getLegalIdentity();
Party firstCounterparty = getServiceHub().getNetworkMapCache().getPartyNodes().get(0).getLegalIdentity();
Party namedCounterparty = getServiceHub().getIdentityService().partyFromX500Name(new CordaX500Name("NodeA", "London", "UK"));
Party keyedCounterparty = getServiceHub().getIdentityService().partyFromKey(dummyPubKey);
// DOCEND 2
// Finally, we can use the map to identify nodes providing a
// specific service (e.g. a regulator or an oracle).
// DOCSTART 3
Party regulator = getServiceHub().getNetworkMapCache().getNodesWithService(ServiceType.Companion.getRegulator()).get(0).getLegalIdentity();
Party regulator = getServiceHub().getNetworkMapCache().getPeersWithService(ServiceType.Companion.getRegulator()).get(0).getIdentity().getParty();
// DOCEND 3
/*------------------------------
@ -267,7 +266,7 @@ public class FlowCookbookJava {
// matching every public key in all of the transaction's commands.
// DOCSTART 24
DummyContract.Commands.Create commandData = new DummyContract.Commands.Create();
PublicKey ourPubKey = getServiceHub().getLegalIdentityKey();
PublicKey ourPubKey = getServiceHub().getMyInfo().getLegalIdentitiesAndCerts().get(0).getOwningKey();
PublicKey counterpartyPubKey = counterparty.getOwningKey();
List<PublicKey> requiredSigners = ImmutableList.of(ourPubKey, counterpartyPubKey);
Command<DummyContract.Commands.Create> ourCommand = new Command<>(commandData, requiredSigners);

View File

@ -113,7 +113,7 @@ fun generateTransactions(proxy: CordaRPCOps) {
val issueRef = OpaqueBytes.of(0)
val parties = proxy.networkMapSnapshot()
val notary = parties.first { it.advertisedServices.any { it.info.type.isNotary() } }.notaryIdentity
val me = proxy.nodeIdentity().legalIdentity
val me = proxy.nodeInfo().legalIdentities.first()
while (true) {
Thread.sleep(1000)
val random = SplittableRandom()

View File

@ -20,6 +20,7 @@ import net.corda.finance.flows.AbstractCashFlow
import net.corda.finance.flows.CashException
import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow
import net.corda.testing.chooseIdentity
import java.util.*
// DOCSTART CustomVaultQuery
@ -139,7 +140,7 @@ object TopupIssuerFlow {
val issueTx = subFlow(issueCashFlow)
// NOTE: issueCashFlow performs a Broadcast (which stores a local copy of the txn to the ledger)
// short-circuit when issuing to self
if (issueTo == serviceHub.myInfo.legalIdentity)
if (issueTo == serviceHub.myInfo.chooseIdentity())
return issueTx
// now invoke Cash subflow to Move issued assetType to issue requester
progressTracker.currentStep = TRANSFERRING

View File

@ -112,18 +112,17 @@ object FlowCookbook {
val firstNotary: Party = serviceHub.networkMapCache.notaryNodes[0].notaryIdentity
// DOCEND 1
// We may also need to identify a specific counterparty. Again, we
// do so using the network map.
// We may also need to identify a specific counterparty. We
// do so using identity service.
// DOCSTART 2
val namedCounterparty: Party? = serviceHub.networkMapCache.getNodeByLegalName(CordaX500Name(organisation = "NodeA", locality = "London", country = "UK"))?.legalIdentity
val keyedCounterparty: Party? = serviceHub.networkMapCache.getNodeByLegalIdentityKey(dummyPubKey)?.legalIdentity
val firstCounterparty: Party = serviceHub.networkMapCache.partyNodes[0].legalIdentity
val namedCounterparty: Party? = serviceHub.identityService.partyFromX500Name(CordaX500Name(organisation = "NodeA", locality = "London", country = "UK"))
val keyedCounterparty: Party? = serviceHub.identityService.partyFromKey(dummyPubKey)
// DOCEND 2
// Finally, we can use the map to identify nodes providing a
// specific service (e.g. a regulator or an oracle).
// DOCSTART 3
val regulator: Party = serviceHub.networkMapCache.getNodesWithService(ServiceType.regulator)[0].legalIdentity
val regulator: Party = serviceHub.networkMapCache.getPeersWithService(ServiceType.regulator)[0].identity.party
// DOCEND 3
/**-----------------------------
@ -248,7 +247,7 @@ object FlowCookbook {
// matching every public key in all of the transaction's commands.
// DOCSTART 24
val commandData: DummyContract.Commands.Create = DummyContract.Commands.Create()
val ourPubKey: PublicKey = serviceHub.legalIdentityKey
val ourPubKey: PublicKey = serviceHub.myInfo.legalIdentitiesAndCerts.first().owningKey
val counterpartyPubKey: PublicKey = counterparty.owningKey
val requiredSigners: List<PublicKey> = listOf(ourPubKey, counterpartyPubKey)
val ourCommand: Command<DummyContract.Commands.Create> = Command(commandData, requiredSigners)

View File

@ -17,6 +17,7 @@ import net.corda.core.utilities.unwrap
import net.corda.finance.contracts.asset.CASH_PROGRAM_ID
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.schemas.CashSchemaV1
import net.corda.testing.chooseIdentity
import java.util.*
@CordaSerializable
@ -74,7 +75,7 @@ private fun prepareOurInputsAndOutputs(serviceHub: ServiceHub, lockId: UUID, req
val outputs = if (residual > 0L) {
// Build an output state for the residual change back to us
val residualAmount = Amount(residual, sellAmount.token)
val residualOutput = Cash.State(residualAmount, serviceHub.myInfo.legalIdentity)
val residualOutput = Cash.State(residualAmount, serviceHub.myInfo.chooseIdentity())
listOf(transferedFundsOutput, residualOutput)
} else {
listOf(transferedFundsOutput)
@ -96,11 +97,11 @@ class ForeignExchangeFlow(val tradeId: String,
// Select correct sides of the Fx exchange to query for.
// Specifically we own the assets we wish to sell.
// Also prepare the other side query
val (localRequest, remoteRequest) = if (baseCurrencySeller == serviceHub.myInfo.legalIdentity) {
val (localRequest, remoteRequest) = if (baseCurrencySeller == serviceHub.myInfo.chooseIdentity()) {
val local = FxRequest(tradeId, baseCurrencyAmount, baseCurrencySeller, baseCurrencyBuyer)
val remote = FxRequest(tradeId, quoteCurrencyAmount, baseCurrencyBuyer, baseCurrencySeller)
Pair(local, remote)
} else if (baseCurrencyBuyer == serviceHub.myInfo.legalIdentity) {
} else if (baseCurrencyBuyer == serviceHub.myInfo.chooseIdentity()) {
val local = FxRequest(tradeId, quoteCurrencyAmount, baseCurrencyBuyer, baseCurrencySeller)
val remote = FxRequest(tradeId, baseCurrencyAmount, baseCurrencySeller, baseCurrencyBuyer)
Pair(local, remote)
@ -132,7 +133,7 @@ class ForeignExchangeFlow(val tradeId: String,
>= remoteRequestWithNotary.amount.quantity) {
"the provided inputs don't provide sufficient funds"
}
require(it.filter { it.owner == serviceHub.myInfo.legalIdentity }.
require(it.filter { it.owner == serviceHub.myInfo.chooseIdentity() }.
map { it.amount.quantity }.sum() == remoteRequestWithNotary.amount.quantity) {
"the provided outputs don't provide the request quantity"
}
@ -205,7 +206,7 @@ class ForeignExchangeRemoteFlow(val source: Party) : FlowLogic<Unit>() {
// the lifecycle of the Fx trades which would be included in the transaction
// Check request is for us
require(serviceHub.myInfo.legalIdentity == it.owner) {
require(serviceHub.myInfo.chooseIdentity() == it.owner) {
"Request does not include the correct counterparty"
}
require(source == it.counterparty) {

View File

@ -17,6 +17,7 @@ import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.seconds
import net.corda.core.utilities.unwrap
import net.corda.testing.chooseIdentity
// Minimal state model of a manual approval process
@CordaSerializable
@ -102,7 +103,7 @@ class SubmitTradeApprovalFlow(val tradeId: String,
// Manufacture an initial state
val tradeProposal = TradeApprovalContract.State(
tradeId,
serviceHub.myInfo.legalIdentity,
serviceHub.myInfo.chooseIdentity(),
counterparty)
// identify a notary. This might also be done external to the flow
val notary = serviceHub.networkMapCache.getAnyNotary()
@ -113,7 +114,7 @@ class SubmitTradeApprovalFlow(val tradeId: String,
// We can automatically sign as there is no untrusted data.
val signedTx = serviceHub.signInitialTransaction(tx)
// Notarise and distribute.
subFlow(FinalityFlow(signedTx, setOf(serviceHub.myInfo.legalIdentity, counterparty)))
subFlow(FinalityFlow(signedTx, setOf(serviceHub.myInfo.chooseIdentity(), counterparty)))
// Return the initial state
return signedTx.tx.outRef<TradeApprovalContract.State>(0)
}
@ -148,7 +149,7 @@ class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : Flow
"Input trade not modifiable ${latestRecord.state.data.state}"
}
// Check we are the correct Party to run the protocol. Note they will counter check this too.
require(latestRecord.state.data.counterparty == serviceHub.myInfo.legalIdentity) {
require(latestRecord.state.data.counterparty == serviceHub.myInfo.chooseIdentity()) {
"The counterparty must give the verdict"
}
@ -170,7 +171,7 @@ class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : Flow
latestRecord,
StateAndContract(newState, TRADE_APPROVAL_PROGRAM_ID),
Command(TradeApprovalContract.Commands.Completed(),
listOf(serviceHub.myInfo.legalIdentity.owningKey, latestRecord.state.data.source.owningKey)))
listOf(serviceHub.myInfo.chooseIdentity().owningKey, latestRecord.state.data.source.owningKey)))
tx.setTimeWindow(serviceHub.clock.instant(), 60.seconds)
// We can sign this transaction immediately as we have already checked all the fields and the decision
// is ultimately a manual one from the caller.
@ -213,7 +214,7 @@ class RecordCompletionFlow(val source: Party) : FlowLogic<Unit>() {
// First we receive the verdict transaction signed by their single key
val completeTx = receive<SignedTransaction>(source).unwrap {
// Check the transaction is signed apart from our own key and the notary
it.verifySignaturesExcept(serviceHub.myInfo.legalIdentity.owningKey, it.tx.notary!!.owningKey)
it.verifySignaturesExcept(serviceHub.myInfo.chooseIdentity().owningKey, it.tx.notary!!.owningKey)
// Check the transaction data is correctly formed
val ltx = it.toLedgerTransaction(serviceHub, false)
ltx.verify()
@ -224,7 +225,7 @@ class RecordCompletionFlow(val source: Party) : FlowLogic<Unit>() {
// Check the context dependent parts of the transaction as the
// Contract verify method must not use serviceHub queries.
val state = ltx.outRef<TradeApprovalContract.State>(0)
require(state.state.data.source == serviceHub.myInfo.legalIdentity) {
require(state.state.data.source == serviceHub.myInfo.chooseIdentity()) {
"Proposal not one of our original proposals"
}
require(state.state.data.counterparty == source) {

View File

@ -13,6 +13,7 @@ import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.DUMMY_NOTARY_KEY
import net.corda.testing.chooseIdentity
import net.corda.testing.node.MockNetwork
import org.junit.After
import org.junit.Assert
@ -77,9 +78,9 @@ class CustomVaultQueryTest {
private fun topUpCurrencies() {
val flowHandle1 = nodeA.services.startFlow(TopupIssuerFlow.TopupIssuanceRequester(
nodeA.info.legalIdentity,
nodeA.info.chooseIdentity(),
OpaqueBytes.of(0x01),
nodeA.info.legalIdentity,
nodeA.info.chooseIdentity(),
notaryNode.info.notaryIdentity))
flowHandle1.resultFuture.getOrThrow()
}

View File

@ -13,6 +13,7 @@ import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.DUMMY_NOTARY_KEY
import net.corda.testing.chooseIdentity
import net.corda.testing.node.MockNetwork
import org.junit.After
import org.junit.Before
@ -69,10 +70,10 @@ class FxTransactionBuildTutorialTest {
// Now run the actual Fx exchange
val doIt = nodeA.services.startFlow(ForeignExchangeFlow("trade1",
POUNDS(100).issuedBy(nodeB.info.legalIdentity.ref(0x01)),
DOLLARS(200).issuedBy(nodeA.info.legalIdentity.ref(0x01)),
nodeA.info.legalIdentity,
nodeB.info.legalIdentity))
POUNDS(100).issuedBy(nodeB.info.chooseIdentity().ref(0x01)),
DOLLARS(200).issuedBy(nodeA.info.chooseIdentity().ref(0x01)),
nodeA.info.chooseIdentity(),
nodeB.info.chooseIdentity()))
// wait for the flow to finish and the vault updates to be done
doIt.resultFuture.getOrThrow()
// Get the balances when the vault updates

View File

@ -14,6 +14,7 @@ import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.DUMMY_NOTARY_KEY
import net.corda.testing.chooseIdentity
import net.corda.testing.node.MockNetwork
import org.junit.After
import org.junit.Before
@ -55,7 +56,7 @@ class WorkflowTransactionBuildTutorialTest {
// Setup a vault subscriber to wait for successful upload of the proposal to NodeB
val nodeBVaultUpdate = nodeB.services.vaultService.updates.toFuture()
// Kick of the proposal flow
val flow1 = nodeA.services.startFlow(SubmitTradeApprovalFlow("1234", nodeB.info.legalIdentity))
val flow1 = nodeA.services.startFlow(SubmitTradeApprovalFlow("1234", nodeB.info.chooseIdentity()))
// Wait for the flow to finish
val proposalRef = flow1.resultFuture.getOrThrow()
val proposalLinearId = proposalRef.state.data.linearId
@ -71,8 +72,8 @@ class WorkflowTransactionBuildTutorialTest {
// Confirm the state as as expected
assertEquals(WorkflowState.NEW, proposalRef.state.data.state)
assertEquals("1234", proposalRef.state.data.tradeId)
assertEquals(nodeA.info.legalIdentity, proposalRef.state.data.source)
assertEquals(nodeB.info.legalIdentity, proposalRef.state.data.counterparty)
assertEquals(nodeA.info.chooseIdentity(), proposalRef.state.data.source)
assertEquals(nodeB.info.chooseIdentity(), proposalRef.state.data.counterparty)
assertEquals(proposalRef, latestFromA)
assertEquals(proposalRef, latestFromB)
// Setup a vault subscriber to pause until the final update is in NodeA and NodeB
@ -95,8 +96,8 @@ class WorkflowTransactionBuildTutorialTest {
// Confirm the state is as expected
assertEquals(WorkflowState.APPROVED, completedRef.state.data.state)
assertEquals("1234", completedRef.state.data.tradeId)
assertEquals(nodeA.info.legalIdentity, completedRef.state.data.source)
assertEquals(nodeB.info.legalIdentity, completedRef.state.data.counterparty)
assertEquals(nodeA.info.chooseIdentity(), completedRef.state.data.source)
assertEquals(nodeB.info.chooseIdentity(), completedRef.state.data.counterparty)
assertEquals(completedRef, finalFromA)
assertEquals(completedRef, finalFromB)
}