Updated samples and demos to use new Vault Query service. (#924)

* Updated all sample code to use new Vault Query service APIs.

* Fix broken Unit test.

* Added missing transaction boundary.

* Fix broken ScheduledFlow test (caused by assertion on non-ordered collection)

* Remove redundant negative test (as new Vault Query no longer returns iterators).

* Whitespace formatting fixed following PR review from SA.

* Force query to specify a PAGE SIZE equivalent to total states to be exited (RP review comment).

* Use single (and fail fast) instead of first - when only expecting a single result.

* Demonstrate paging and sorting; failfast on single expected result.

* Enhancement: added Sorting by CommonStateAttribute (StateRef txnId and index)

* Fix: incorrect total states count.

* Fixed incorrect total states counting.

* Remove redundant filter (UNCONSUMED).

* Updated tutorial code and associated documentation (building transactions).

* Updated all vaultAndUpdates to vault[Track|Query]By.

* Temporary disable failing Vault Query tests (awaiting pagination PR fix).

* Rebase from master to pick up pagination changes/fix.

* Fixed criteria filter on track.

* Cleanup redundant print output.

* Refactor to extract common function for Vault Query paging and sorting.

* Identified problem in SimmValuation demo failing test caused by query by single participant in participants list (not yet supported in VaultQuery criteria).

* Minor fixes following rebase from master.

* Minor updates following rebase.

* Removed redundant import.

* Fixed type casting error.

* Minor fixes following rebase from master.

* VQ Fix - applied in other PR.

* Removed duplication after rebase and minor fix to failing smoke test.
This commit is contained in:
josecoll
2017-08-03 11:47:15 +01:00
committed by GitHub
parent 73528d287d
commit 64ba8d3a88
33 changed files with 284 additions and 286 deletions

View File

@ -7,6 +7,7 @@ import net.corda.core.contracts.ContractState
import net.corda.core.contracts.DOLLARS
import net.corda.core.getOrThrow
import net.corda.core.messaging.startFlow
import net.corda.core.messaging.vaultTrackBy
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.Vault
import net.corda.core.node.services.vault.QueryCriteria
@ -59,9 +60,8 @@ class IntegrationTestingTutorial {
// END 2
// START 3
val criteria = QueryCriteria.VaultQueryCriteria(status = Vault.StateStatus.ALL)
val (_, bobVaultUpdates) = bobProxy.vaultTrackByCriteria<Cash.State>(Cash.State::class.java, criteria)
val (_, aliceVaultUpdates) = aliceProxy.vaultTrackByCriteria<Cash.State>(Cash.State::class.java, criteria)
val bobVaultUpdates = bobProxy.vaultTrackBy<Cash.State>().updates
val aliceVaultUpdates = aliceProxy.vaultTrackBy<Cash.State>().updates
// END 3
// START 4

View File

@ -6,6 +6,7 @@ import net.corda.core.contracts.Amount
import net.corda.core.contracts.USD
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.startFlow
import net.corda.core.messaging.vaultQueryBy
import net.corda.core.node.CordaPluginRegistry
import net.corda.core.node.services.ServiceInfo
import net.corda.core.serialization.CordaSerializable
@ -105,10 +106,10 @@ fun main(args: Array<String>) {
// START 6
fun generateTransactions(proxy: CordaRPCOps) {
val (vault, vaultUpdates) = proxy.vaultAndUpdates()
vaultUpdates.notUsed()
val vault = proxy.vaultQueryBy<Cash.State>().states
var ownedQuantity = vault.fold(0L) { sum, state ->
sum + (state.state.data as Cash.State).amount.quantity
sum + state.state.data.amount.quantity
}
val issueRef = OpaqueBytes.of(0)
val (parties, partyUpdates) = proxy.networkMapFeed()

View File

@ -10,13 +10,14 @@ import net.corda.core.crypto.SecureHash
import net.corda.core.flows.*
import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub
import net.corda.core.node.services.Vault
import net.corda.core.node.services.queryBy
import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.node.services.vault.builder
import net.corda.core.serialization.CordaSerializable
import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.unwrap
import net.corda.schemas.CashSchemaV1
import java.util.*
@CordaSerializable
@ -36,18 +37,18 @@ private data class FxResponse(val inputs: List<StateAndRef<Cash.State>>,
private fun gatherOurInputs(serviceHub: ServiceHub,
amountRequired: Amount<Issued<Currency>>,
notary: Party?): Pair<List<StateAndRef<Cash.State>>, Long> {
// Collect cash type inputs
val queryCriteria = QueryCriteria.VaultQueryCriteria(Vault.StateStatus.UNCONSUMED, setOf(Cash.State::class.java))
val cashStates = serviceHub.vaultQueryService.queryBy<Cash.State>(queryCriteria).states
// extract our identity for convenience
val ourKeys = serviceHub.keyManagementService.keys
// Filter down to our own cash states with right currency and issuer
val suitableCashStates = cashStates.filter {
val state = it.state.data
// TODO: We may want to have the list of our states pre-cached somewhere for performance
(state.owner.owningKey in ourKeys) && (state.amount.token == amountRequired.token)
}
val ourParties = ourKeys.map { serviceHub.identityService.partyFromKey(it) ?: throw IllegalStateException("Unable to resolve party from key") }
val fungibleCriteria = QueryCriteria.FungibleAssetQueryCriteria(owner = ourParties)
val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.equal(amountRequired.token.product.currencyCode) }
val cashCriteria = QueryCriteria.VaultCustomQueryCriteria(logicalExpression)
// Collect cash type inputs
val suitableCashStates = serviceHub.vaultQueryService.queryBy<Cash.State>(fungibleCriteria.and(cashCriteria)).states
require(!suitableCashStates.isEmpty()) { "Insufficient funds" }
var remaining = amountRequired.quantity
// We will need all of the inputs to be on the same notary.
// For simplicity we just filter on the first notary encountered

View File

@ -12,7 +12,9 @@ import net.corda.core.flows.InitiatingFlow
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub
import net.corda.core.node.services.linearHeadsOfType
import net.corda.core.node.services.Vault
import net.corda.core.node.services.queryBy
import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria
import net.corda.core.serialization.CordaSerializable
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.SignedTransaction
@ -21,15 +23,6 @@ import net.corda.core.utilities.seconds
import net.corda.core.utilities.unwrap
import java.security.PublicKey
// DOCSTART 1
// Helper method to locate the latest Vault version of a LinearState from a possibly out of date StateRef
inline fun <reified T : LinearState> ServiceHub.latest(ref: StateRef): StateAndRef<T> {
val linearHeads = vaultService.linearHeadsOfType<T>()
val original = toStateAndRef<T>(ref)
return linearHeads[original.state.data.linearId]!!
}
// DOCEND 1
// Minimal state model of a manual approval process
@CordaSerializable
enum class WorkflowState {
@ -150,8 +143,11 @@ class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : Flow
@Suspendable
override fun call(): StateAndRef<TradeApprovalContract.State> {
// Pull in the latest Vault version of the StateRef as a full StateAndRef
val latestRecord = serviceHub.latest<TradeApprovalContract.State>(ref)
// DOCSTART 1
val criteria = VaultQueryCriteria(stateRefs = listOf(ref))
val latestRecord = serviceHub.vaultQueryService.queryBy<TradeApprovalContract.State>(criteria).states.single()
// DOCEND 1
// Check the protocol hasn't already been run
require(latestRecord.ref == ref) {
"Input trade $ref is not latest version $latestRecord"

View File

@ -38,7 +38,6 @@ class FxTransactionBuildTutorialTest {
@After
fun cleanUp() {
println("Close DB")
mockNet.stopNodes()
}

View File

@ -26,10 +26,9 @@ class WorkflowTransactionBuildTutorialTest {
lateinit var nodeA: MockNetwork.MockNode
lateinit var nodeB: MockNetwork.MockNode
// Helper method to locate the latest Vault version of a LinearState from a possibly out of date StateRef
// Helper method to locate the latest Vault version of a LinearState
private inline fun <reified T : LinearState> ServiceHub.latest(ref: UniqueIdentifier): StateAndRef<T> {
val linearHeads = vaultQueryService.queryBy<T>(QueryCriteria.LinearStateQueryCriteria(linearId = listOf(ref))
.and(QueryCriteria.VaultQueryCriteria(status = Vault.StateStatus.UNCONSUMED)))
val linearHeads = vaultQueryService.queryBy<T>(QueryCriteria.LinearStateQueryCriteria(linearId = listOf(ref)))
return linearHeads.states.single()
}
@ -48,7 +47,6 @@ class WorkflowTransactionBuildTutorialTest {
@After
fun cleanUp() {
println("Close DB")
mockNet.stopNodes()
}