Removes use of notaries.first. (#6008)

This commit is contained in:
Joel Dudley 2020-02-27 13:27:38 +00:00 committed by GitHub
parent 92a437f333
commit 1bf311ce4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 56 additions and 38 deletions

View File

@ -215,7 +215,7 @@ Remember that a transaction generally needs a notary to:
* Prevent double-spends if the transaction has inputs * Prevent double-spends if the transaction has inputs
* Serve as a timestamping authority if the transaction has a time-window * Serve as a timestamping authority if the transaction has a time-window
There are several ways to retrieve a notary from the network map: A notary can be retrieved from the network map as follows:
.. container:: codeset .. container:: codeset

View File

@ -117,19 +117,14 @@ public class FlowCookbook {
progressTracker.setCurrentStep(ID_OTHER_NODES); progressTracker.setCurrentStep(ID_OTHER_NODES);
// DOCEND 18 // DOCEND 18
// A transaction generally needs a notary: // Every transaction needs a notary:
// - To prevent double-spends if the transaction has inputs // - To prevent double-spends if the transaction has inputs
// - To serve as a timestamping authority if the transaction has a // - To serve as a timestamping authority if the transaction has a
// time-window // time-window
// We retrieve a notary from the network map. // We retrieve a notary from the network map.
// DOCSTART 01 // DOCSTART 01
CordaX500Name notaryName = new CordaX500Name("Notary Service", "London", "GB"); CordaX500Name notaryName = new CordaX500Name("Notary Service", "London", "GB");
Party specificNotary = getServiceHub().getNetworkMapCache().getNotary(notaryName); Party notary = getServiceHub().getNetworkMapCache().getNotary(notaryName);
// Alternatively, we can pick an arbitrary notary from the notary
// list. However, it is always preferable to specify the notary
// explicitly, as the notary list might change when new notaries are
// introduced, or old ones decommissioned.
Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
// DOCEND 01 // DOCEND 01
// We may also need to identify a specific counterparty. We do so // We may also need to identify a specific counterparty. We do so
@ -328,7 +323,7 @@ public class FlowCookbook {
// If our transaction has input states or a time-window, we must instantiate it with a // If our transaction has input states or a time-window, we must instantiate it with a
// notary. // notary.
// DOCSTART 19 // DOCSTART 19
TransactionBuilder txBuilder = new TransactionBuilder(specificNotary); TransactionBuilder txBuilder = new TransactionBuilder(notary);
// DOCEND 19 // DOCEND 19
// Otherwise, we can choose to instantiate it without one: // Otherwise, we can choose to instantiate it without one:
@ -362,7 +357,7 @@ public class FlowCookbook {
// An output state can be added as a ``ContractState``, contract class name and notary. // An output state can be added as a ``ContractState``, contract class name and notary.
// DOCSTART 49 // DOCSTART 49
txBuilder.addOutputState(ourOutputState, DummyContract.PROGRAM_ID, specificNotary); txBuilder.addOutputState(ourOutputState, DummyContract.PROGRAM_ID, notary);
// DOCEND 49 // DOCEND 49
// We can also leave the notary field blank, in which case the transaction's default // We can also leave the notary field blank, in which case the transaction's default
// notary is used. // notary is used.
@ -372,7 +367,7 @@ public class FlowCookbook {
// Or we can add the output state as a ``TransactionState``, which already specifies // Or we can add the output state as a ``TransactionState``, which already specifies
// the output's contract and notary. // the output's contract and notary.
// DOCSTART 51 // DOCSTART 51
TransactionState txState = new TransactionState(ourOutputState, DummyContract.PROGRAM_ID, specificNotary); TransactionState txState = new TransactionState(ourOutputState, DummyContract.PROGRAM_ID, notary);
// DOCEND 51 // DOCEND 51
// Commands can be added as ``Command``s. // Commands can be added as ``Command``s.

View File

@ -97,7 +97,7 @@ class InitiatorFlow(val arg1: Boolean, val arg2: Int, private val counterparty:
progressTracker.currentStep = ID_OTHER_NODES progressTracker.currentStep = ID_OTHER_NODES
// DOCEND 18 // DOCEND 18
// A transaction generally needs a notary: // Every transaction needs a notary:
// - To prevent double-spends if the transaction has inputs // - To prevent double-spends if the transaction has inputs
// - To serve as a timestamping authority if the transaction has a // - To serve as a timestamping authority if the transaction has a
// time-window // time-window
@ -107,12 +107,7 @@ class InitiatorFlow(val arg1: Boolean, val arg2: Int, private val counterparty:
organisation = "Notary Service", organisation = "Notary Service",
locality = "London", locality = "London",
country = "GB") country = "GB")
val specificNotary: Party = serviceHub.networkMapCache.getNotary(notaryName)!! val notary: Party = serviceHub.networkMapCache.getNotary(notaryName)!!
// Alternatively, we can pick an arbitrary notary from the notary
// list. However, it is always preferable to specify the notary
// explicitly, as the notary list might change when new notaries are
// introduced, or old ones decommissioned.
val firstNotary: Party = serviceHub.networkMapCache.notaryIdentities.first()
// DOCEND 01 // DOCEND 01
// We may also need to identify a specific counterparty. We do so // We may also need to identify a specific counterparty. We do so
@ -328,7 +323,7 @@ class InitiatorFlow(val arg1: Boolean, val arg2: Int, private val counterparty:
// If our transaction has input states or a time-window, we must instantiate it with a // If our transaction has input states or a time-window, we must instantiate it with a
// notary. // notary.
// DOCSTART 19 // DOCSTART 19
val txBuilder: TransactionBuilder = TransactionBuilder(specificNotary) val txBuilder: TransactionBuilder = TransactionBuilder(notary)
// DOCEND 19 // DOCEND 19
// Otherwise, we can choose to instantiate it without one: // Otherwise, we can choose to instantiate it without one:
@ -362,7 +357,7 @@ class InitiatorFlow(val arg1: Boolean, val arg2: Int, private val counterparty:
// An output state can be added as a ``ContractState``, contract class name and notary. // An output state can be added as a ``ContractState``, contract class name and notary.
// DOCSTART 49 // DOCSTART 49
txBuilder.addOutputState(ourOutputState, DummyContract.PROGRAM_ID, specificNotary) txBuilder.addOutputState(ourOutputState, DummyContract.PROGRAM_ID, notary)
// DOCEND 49 // DOCEND 49
// We can also leave the notary field blank, in which case the transaction's default // We can also leave the notary field blank, in which case the transaction's default
// notary is used. // notary is used.
@ -372,7 +367,7 @@ class InitiatorFlow(val arg1: Boolean, val arg2: Int, private val counterparty:
// Or we can add the output state as a ``TransactionState``, which already specifies // Or we can add the output state as a ``TransactionState``, which already specifies
// the output's contract and notary. // the output's contract and notary.
// DOCSTART 51 // DOCSTART 51
val txState: TransactionState<DummyState> = TransactionState(ourOutputState, DummyContract.PROGRAM_ID, specificNotary) val txState: TransactionState<DummyState> = TransactionState(ourOutputState, DummyContract.PROGRAM_ID, notary)
// DOCEND 51 // DOCEND 51
// Commands can be added as ``Command``s. // Commands can be added as ``Command``s.

View File

@ -1,10 +1,23 @@
package net.corda.docs.kotlin package net.corda.docs.kotlin
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.* import net.corda.core.contracts.Amount
import net.corda.core.contracts.Issued
import net.corda.core.contracts.StateAndContract
import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.withoutIssuer
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.TransactionSignature import net.corda.core.crypto.TransactionSignature
import net.corda.core.flows.* import net.corda.core.flows.FinalityFlow
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowSession
import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.ReceiveFinalityFlow
import net.corda.core.flows.ReceiveStateAndRefFlow
import net.corda.core.flows.ReceiveTransactionFlow
import net.corda.core.flows.SendStateAndRefFlow
import net.corda.core.flows.SendTransactionFlow
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
@ -24,7 +37,7 @@ private data class FxRequest(val tradeId: String,
val amount: Amount<Issued<Currency>>, val amount: Amount<Issued<Currency>>,
val owner: Party, val owner: Party,
val counterparty: Party, val counterparty: Party,
val notary: Party? = null) val notary: Party)
// DOCSTART 1 // DOCSTART 1
// This is equivalent to the Cash.generateSpend // This is equivalent to the Cash.generateSpend
@ -38,8 +51,7 @@ private fun gatherOurInputs(serviceHub: ServiceHub,
val ourParties = ourKeys.map { serviceHub.identityService.partyFromKey(it) ?: throw IllegalStateException("Unable to resolve party from key") } val ourParties = ourKeys.map { serviceHub.identityService.partyFromKey(it) ?: throw IllegalStateException("Unable to resolve party from key") }
val fungibleCriteria = QueryCriteria.FungibleAssetQueryCriteria(owner = ourParties) val fungibleCriteria = QueryCriteria.FungibleAssetQueryCriteria(owner = ourParties)
val notaries = notary ?: serviceHub.networkMapCache.notaryIdentities.first() val vaultCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notary = listOf(notary as AbstractParty))
val vaultCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notary = listOf(notaries as AbstractParty))
val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.equal(amountRequired.token.product.currencyCode) } val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.equal(amountRequired.token.product.currencyCode) }
val cashCriteria = QueryCriteria.VaultCustomQueryCriteria(logicalExpression) val cashCriteria = QueryCriteria.VaultCustomQueryCriteria(logicalExpression)
@ -90,19 +102,20 @@ class ForeignExchangeFlow(private val tradeId: String,
private val baseCurrencyAmount: Amount<Issued<Currency>>, private val baseCurrencyAmount: Amount<Issued<Currency>>,
private val quoteCurrencyAmount: Amount<Issued<Currency>>, private val quoteCurrencyAmount: Amount<Issued<Currency>>,
private val counterparty: Party, private val counterparty: Party,
private val weAreBaseCurrencySeller: Boolean) : FlowLogic<SecureHash>() { private val weAreBaseCurrencySeller: Boolean,
private val notary: Party) : FlowLogic<SecureHash>() {
@Suspendable @Suspendable
override fun call(): SecureHash { override fun call(): SecureHash {
// Select correct sides of the Fx exchange to query for. // Select correct sides of the Fx exchange to query for.
// Specifically we own the assets we wish to sell. // Specifically we own the assets we wish to sell.
// Also prepare the other side query // Also prepare the other side query
val (localRequest, remoteRequest) = if (weAreBaseCurrencySeller) { val (localRequest, remoteRequest) = if (weAreBaseCurrencySeller) {
val local = FxRequest(tradeId, baseCurrencyAmount, ourIdentity, counterparty) val local = FxRequest(tradeId, baseCurrencyAmount, ourIdentity, counterparty, notary)
val remote = FxRequest(tradeId, quoteCurrencyAmount, counterparty, ourIdentity) val remote = FxRequest(tradeId, quoteCurrencyAmount, counterparty, ourIdentity, notary)
Pair(local, remote) Pair(local, remote)
} else { } else {
val local = FxRequest(tradeId, quoteCurrencyAmount, ourIdentity, counterparty) val local = FxRequest(tradeId, quoteCurrencyAmount, ourIdentity, counterparty, notary)
val remote = FxRequest(tradeId, baseCurrencyAmount, counterparty, ourIdentity) val remote = FxRequest(tradeId, baseCurrencyAmount, counterparty, ourIdentity, notary)
Pair(local, remote) Pair(local, remote)
} }

View File

@ -3,9 +3,24 @@
package net.corda.docs.kotlin.txbuild package net.corda.docs.kotlin.txbuild
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.* import net.corda.core.contracts.Command
import net.corda.core.contracts.CommandData
import net.corda.core.contracts.Contract
import net.corda.core.contracts.LinearState
import net.corda.core.contracts.StateAndContract
import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TypeOnlyCommandData
import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.contracts.requireSingleCommand
import net.corda.core.contracts.requireThat
import net.corda.core.crypto.TransactionSignature import net.corda.core.crypto.TransactionSignature
import net.corda.core.flows.* import net.corda.core.flows.FinalityFlow
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowSession
import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.ReceiveFinalityFlow
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.services.queryBy import net.corda.core.node.services.queryBy
@ -95,13 +110,12 @@ data class TradeApprovalContract(val blank: Unit? = null) : Contract {
*/ */
@InitiatingFlow @InitiatingFlow
class SubmitTradeApprovalFlow(private val tradeId: String, class SubmitTradeApprovalFlow(private val tradeId: String,
private val counterparty: Party) : FlowLogic<StateAndRef<TradeApprovalContract.State>>() { private val counterparty: Party,
private val notary: Party) : FlowLogic<StateAndRef<TradeApprovalContract.State>>() {
@Suspendable @Suspendable
override fun call(): StateAndRef<TradeApprovalContract.State> { override fun call(): StateAndRef<TradeApprovalContract.State> {
// Manufacture an initial state // Manufacture an initial state
val tradeProposal = TradeApprovalContract.State(tradeId, ourIdentity, counterparty) val tradeProposal = TradeApprovalContract.State(tradeId, ourIdentity, counterparty)
// identify a notary. This might also be done external to the flow
val notary = serviceHub.networkMapCache.notaryIdentities.first()
// Create the TransactionBuilder and populate with the new state. // Create the TransactionBuilder and populate with the new state.
val tx = TransactionBuilder(notary).withItems( val tx = TransactionBuilder(notary).withItems(
StateAndContract(tradeProposal, TRADE_APPROVAL_PROGRAM_ID), StateAndContract(tradeProposal, TRADE_APPROVAL_PROGRAM_ID),

View File

@ -58,7 +58,8 @@ class FxTransactionBuildTutorialTest {
POUNDS(100).issuedBy(nodeB.info.singleIdentity().ref(0x01)), POUNDS(100).issuedBy(nodeB.info.singleIdentity().ref(0x01)),
DOLLARS(200).issuedBy(nodeA.info.singleIdentity().ref(0x01)), DOLLARS(200).issuedBy(nodeA.info.singleIdentity().ref(0x01)),
nodeB.info.singleIdentity(), nodeB.info.singleIdentity(),
weAreBaseCurrencySeller = false)).getOrThrow() weAreBaseCurrencySeller = false,
notary = mockNet.defaultNotaryIdentity)).getOrThrow()
// wait for the flow to finish and the vault updates to be done // wait for the flow to finish and the vault updates to be done
// Get the balances when the vault updates // Get the balances when the vault updates
nodeAVaultUpdate.get() nodeAVaultUpdate.get()

View File

@ -51,7 +51,7 @@ class WorkflowTransactionBuildTutorialTest {
// Setup a vault subscriber to wait for successful upload of the proposal to NodeB // Setup a vault subscriber to wait for successful upload of the proposal to NodeB
val nodeBVaultUpdate = bobNode.services.vaultService.updates.toFuture() val nodeBVaultUpdate = bobNode.services.vaultService.updates.toFuture()
// Kick of the proposal flow // Kick of the proposal flow
val flow1 = aliceNode.startFlow(SubmitTradeApprovalFlow("1234", bob)) val flow1 = aliceNode.startFlow(SubmitTradeApprovalFlow("1234", bob, mockNet.defaultNotaryIdentity))
// Wait for the flow to finish // Wait for the flow to finish
val proposalRef = flow1.getOrThrow() val proposalRef = flow1.getOrThrow()
val proposalLinearId = proposalRef.state.data.linearId val proposalLinearId = proposalRef.state.data.linearId