Skip to content

Commit 4b2aeeb

Browse files
Maintenance refactoring. Added LedgerTransaction extensions.
1 parent 1d8e293 commit 4b2aeeb

File tree

11 files changed

+375
-125
lines changed

11 files changed

+375
-125
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
![ONIX Labs](https://raw.githubusercontent.com/onix-labs/onix-labs.github.io/master/content/logo/master_full_md.png)
2+
3+
# Change Log
4+
5+
## Version 1.0.0
6+
7+
8+
9+
10+
11+
12+

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ buildscript {
4242
}
4343

4444
group 'io.onixlabs'
45-
version '1.0.0'
45+
version '1.1.0'
4646

4747
subprojects {
4848
repositories {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package io.onixlabs.corda.core.contract
2+
3+
import net.corda.core.contracts.Command
4+
import net.corda.core.contracts.CommandData
5+
import net.corda.core.contracts.ContractState
6+
import net.corda.core.contracts.StateAndRef
7+
import net.corda.core.transactions.LedgerTransaction
8+
9+
/**
10+
* Obtains a single input ref from a ledger transaction.
11+
*
12+
* @param T The underlying contract state type to obtain.
13+
* @param contractStateClass The class of the contract state type to obtain.
14+
* @return Returns a single input ref from a ledger transaction of the specified type.
15+
*/
16+
fun <T : ContractState> LedgerTransaction.singleInputRefOfType(contractStateClass: Class<T>): StateAndRef<T> {
17+
return inRefsOfType(contractStateClass).single()
18+
}
19+
20+
/**
21+
* Obtains a single input ref from a ledger transaction.
22+
*
23+
* @param T The underlying contract state type to obtain.
24+
* @return Returns a single input ref from a ledger transaction of the specified type.
25+
*/
26+
inline fun <reified T : ContractState> LedgerTransaction.singleInputRefOfType(): StateAndRef<T> {
27+
return singleInputRefOfType(T::class.java)
28+
}
29+
30+
/**
31+
* Obtains a single input from a ledger transaction.
32+
*
33+
* @param T The underlying contract state type to obtain.
34+
* @param contractStateClass The class of the contract state type to obtain.
35+
* @return Returns a single input from a ledger transaction of the specified type.
36+
*/
37+
fun <T : ContractState> LedgerTransaction.singleInputOfType(contractStateClass: Class<T>): T {
38+
return inputsOfType(contractStateClass).single()
39+
}
40+
41+
/**
42+
* Obtains a single input from a ledger transaction.
43+
*
44+
* @param T The underlying contract state type to obtain.
45+
* @return Returns a single input from a ledger transaction of the specified type.
46+
*/
47+
inline fun <reified T : ContractState> LedgerTransaction.singleInputOfType(): T {
48+
return singleInputOfType(T::class.java)
49+
}
50+
51+
/**
52+
* Obtains a single reference input ref from a ledger transaction.
53+
*
54+
* @param T The underlying contract state type to obtain.
55+
* @param contractStateClass The class of the contract state type to obtain.
56+
* @return Returns a single reference input ref from a ledger transaction of the specified type.
57+
*/
58+
fun <T : ContractState> LedgerTransaction.singleReferenceInputRefOfType(contractStateClass: Class<T>): StateAndRef<T> {
59+
return referenceInputRefsOfType(contractStateClass).single()
60+
}
61+
62+
/**
63+
* Obtains a single reference input ref from a ledger transaction.
64+
*
65+
* @param T The underlying contract state type to obtain.
66+
* @return Returns a single reference input ref from a ledger transaction of the specified type.
67+
*/
68+
inline fun <reified T : ContractState> LedgerTransaction.singleReferenceInputRefOfType(): StateAndRef<T> {
69+
return singleReferenceInputRefOfType(T::class.java)
70+
}
71+
72+
/**
73+
* Obtains a single reference input from a ledger transaction.
74+
*
75+
* @param T The underlying contract state type to obtain.
76+
* @param contractStateClass The class of the contract state type to obtain.
77+
* @return Returns a single reference input from a ledger transaction of the specified type.
78+
*/
79+
fun <T : ContractState> LedgerTransaction.singleReferenceInputOfType(contractStateClass: Class<T>): T {
80+
return referenceInputsOfType(contractStateClass).single()
81+
}
82+
83+
/**
84+
* Obtains a single reference input from a ledger transaction.
85+
*
86+
* @param T The underlying contract state type to obtain.
87+
* @return Returns a single reference input from a ledger transaction of the specified type.
88+
*/
89+
inline fun <reified T : ContractState> LedgerTransaction.singleReferenceInputOfType(): T {
90+
return singleReferenceInputOfType(T::class.java)
91+
}
92+
93+
/**
94+
* Obtains a single output ref from a ledger transaction.
95+
*
96+
* @param T The underlying contract state type to obtain.
97+
* @param contractStateClass The class of the contract state type to obtain.
98+
* @return Returns a single output ref from a ledger transaction of the specified type.
99+
*/
100+
fun <T : ContractState> LedgerTransaction.singleOutputRefOfType(contractStateClass: Class<T>): StateAndRef<T> {
101+
return outRefsOfType(contractStateClass).single()
102+
}
103+
104+
/**
105+
* Obtains a single output ref from a ledger transaction.
106+
*
107+
* @param T The underlying contract state type to obtain.
108+
* @return Returns a single output ref from a ledger transaction of the specified type.
109+
*/
110+
inline fun <reified T : ContractState> LedgerTransaction.singleOutputRefOfType(): StateAndRef<T> {
111+
return singleOutputRefOfType(T::class.java)
112+
}
113+
114+
/**
115+
* Obtains a single output from a ledger transaction.
116+
*
117+
* @param T The underlying contract state type to obtain.
118+
* @param contractStateClass The class of the contract state type to obtain.
119+
* @return Returns a single output from a ledger transaction of the specified type.
120+
*/
121+
fun <T : ContractState> LedgerTransaction.singleOutputOfType(contractStateClass: Class<T>): T {
122+
return outputsOfType(contractStateClass).single()
123+
}
124+
125+
/**
126+
* Obtains a single output from a ledger transaction.
127+
*
128+
* @param T The underlying contract state type to obtain.
129+
* @return Returns a single output from a ledger transaction of the specified type.
130+
*/
131+
inline fun <reified T : ContractState> LedgerTransaction.singleOutputOfType(): T {
132+
return singleOutputOfType(T::class.java)
133+
}
134+
135+
/**
136+
* Obtains a single command from a ledger transaction.
137+
*
138+
* @param T The underlying contract state type to obtain.
139+
* @param commandClass The class of the command type to obtain.
140+
* @return Returns a single command from a ledger transaction of the specified type.
141+
*/
142+
fun <T : CommandData> LedgerTransaction.singleCommandOfType(commandClass: Class<T>): Command<T> {
143+
return commandsOfType(commandClass).single()
144+
}
145+
146+
/**
147+
* Obtains a single command from a ledger transaction.
148+
*
149+
* @param T The underlying contract state type to obtain.
150+
* @return Returns a single command from a ledger transaction of the specified type.
151+
*/
152+
inline fun <reified T : CommandData> LedgerTransaction.singleCommandOfType(): Command<T> {
153+
return singleCommandOfType(T::class.java)
154+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package io.onixlabs.corda.core.workflow
2+
3+
import co.paralleluniverse.fibers.Suspendable
4+
import net.corda.core.cordapp.CordappContext
5+
import net.corda.core.flows.FlowLogic
6+
import net.corda.core.identity.CordaX500Name
7+
import net.corda.core.identity.Party
8+
import net.corda.core.internal.randomOrNull
9+
import net.corda.core.node.ServiceHub
10+
11+
/**
12+
* Gets the first available notary.
13+
*/
14+
val FlowLogic<*>.firstNotary: Party
15+
get() = serviceHub.networkMapCache.notaryIdentities.firstOrNull()
16+
?: throw NoSuchElementException("No available notaries.")
17+
18+
/**
19+
* Gets a randomly available notary.
20+
*/
21+
val FlowLogic<*>.randomNotary: Party
22+
get() = serviceHub.networkMapCache.notaryIdentities.randomOrNull()
23+
?: throw NoSuchElementException("No available notaries.")
24+
25+
/**
26+
* Gets the preferred notary from the CorDapp config, or alternatively a default notary in the event that
27+
* a preferred notary has not been specified in the CorDapp config.
28+
*
29+
* @param serviceHub The service hub which will be used to obtain a notary from the config file.
30+
* @param defaultSelector The selector function to obtain a notary if none have been specified in the CorDapp config.
31+
* @return Returns the preferred or default notary.
32+
* @throws IllegalArgumentException If the preferred notary cannot be found in the network map cache.
33+
*/
34+
@Suspendable
35+
fun FlowLogic<*>.getPreferredNotary(
36+
serviceHub: ServiceHub = this.serviceHub,
37+
defaultSelector: (ServiceHub) -> Party = { firstNotary }
38+
): Party {
39+
val cordappContext: CordappContext = serviceHub.getAppContext()
40+
logger.info("Using the specified cordapp for notary selection: ${cordappContext.cordapp.name}")
41+
return if (serviceHub.getAppContext().config.exists("notary")) {
42+
val name = CordaX500Name.parse(serviceHub.getAppContext().config.getString("notary"))
43+
serviceHub.networkMapCache.getNotary(name) ?: throw IllegalArgumentException(
44+
"Notary with the specified name cannot be found in the network map cache: $name."
45+
)
46+
} else defaultSelector(serviceHub)
47+
}
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,12 @@
1-
/**
2-
* Copyright 2020 Matthew Layton
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*/
16-
171
package io.onixlabs.corda.core.workflow
182

193
import co.paralleluniverse.fibers.Suspendable
204
import net.corda.core.contracts.ContractState
21-
import net.corda.core.contracts.StateAndRef
22-
import net.corda.core.contracts.StateRef
23-
import net.corda.core.cordapp.CordappContext
24-
import net.corda.core.crypto.SecureHash
255
import net.corda.core.flows.FlowException
266
import net.corda.core.flows.FlowLogic
277
import net.corda.core.flows.FlowSession
288
import net.corda.core.identity.AbstractParty
29-
import net.corda.core.identity.CordaX500Name
30-
import net.corda.core.identity.Party
31-
import net.corda.core.internal.randomOrNull
32-
import net.corda.core.node.ServiceHub
33-
import net.corda.core.transactions.SignedTransaction
349
import net.corda.core.transactions.TransactionBuilder
35-
import net.corda.core.utilities.ProgressTracker.Step
36-
37-
/**
38-
* Gets the first available notary.
39-
*/
40-
val FlowLogic<*>.firstNotary: Party
41-
get() = serviceHub.networkMapCache.notaryIdentities.firstOrNull()
42-
?: throw NoSuchElementException("No available notaries.")
43-
44-
/**
45-
* Gets a randomly available notary.
46-
*/
47-
val FlowLogic<*>.randomNotary: Party
48-
get() = serviceHub.networkMapCache.notaryIdentities.randomOrNull()
49-
?: throw NoSuchElementException("No available notaries.")
50-
51-
/**
52-
* Gets the preferred notary from the CorDapp config, or alternatively a default notary in the event that
53-
* a preferred notary has not been specified in the CorDapp config.
54-
*
55-
* @param serviceHub The service hub which will be used to obtain a notary from the config file.
56-
* @param defaultSelector The selector function to obtain a notary if none have been specified in the CorDapp config.
57-
* @return Returns the preferred or default notary.
58-
* @throws IllegalArgumentException If the preferred notary cannot be found in the network map cache.
59-
*/
60-
@Suspendable
61-
fun FlowLogic<*>.getPreferredNotary(
62-
serviceHub: ServiceHub = this.serviceHub,
63-
defaultSelector: (ServiceHub) -> Party = { firstNotary }
64-
): Party {
65-
val cordappContext: CordappContext = serviceHub.getAppContext()
66-
logger.info("Using the specified cordapp for notary selection: ${cordappContext.cordapp.name}")
67-
return if (serviceHub.getAppContext().config.exists("notary")) {
68-
val name = CordaX500Name.parse(serviceHub.getAppContext().config.getString("notary"))
69-
serviceHub.networkMapCache.getNotary(name) ?: throw IllegalArgumentException(
70-
"Notary with the specified name cannot be found in the network map cache: $name."
71-
)
72-
} else defaultSelector(serviceHub)
73-
}
74-
75-
/**
76-
* Sets the current progress tracker step.
77-
*
78-
* @param step The progress tracker step.
79-
* @param log Determines whether to log the step.
80-
* @param additionalLogInfo Additional information to log when setting the current step.
81-
*/
82-
@Suspendable
83-
fun FlowLogic<*>.currentStep(step: Step, log: Boolean = true, additionalLogInfo: String? = null) {
84-
progressTracker?.currentStep = step
85-
86-
if (log) {
87-
if (additionalLogInfo.isNullOrBlank()) {
88-
logger.info(step.label)
89-
} else {
90-
logger.info("${step.label} ($additionalLogInfo)")
91-
}
92-
}
93-
}
9410

9511
/**
9612
* Initiates flow sessions for the specified parties, except for identities that belong to the local node,
@@ -198,43 +114,3 @@ fun FlowLogic<*>.checkSufficientSessions(sessions: Iterable<FlowSession>, transa
198114
val ledgerTransaction = transaction.toLedgerTransaction(serviceHub)
199115
checkSufficientSessions(sessions, ledgerTransaction.inputStates + ledgerTransaction.outputStates)
200116
}
201-
202-
/**
203-
* Finds a recorded transaction in the vault for the specified transaction hash.
204-
*
205-
* @param transactionHash The transaction hash of the transaction to find.
206-
* @return Returns a [SignedTransaction] for the specified transaction hash.
207-
* @throws FlowException If a signed Transaction cannot be found for the specified transaction hash.
208-
*
209-
*/
210-
@Suspendable
211-
fun FlowLogic<*>.findTransaction(transactionHash: SecureHash): SignedTransaction {
212-
return serviceHub.validatedTransactions.getTransaction(transactionHash)
213-
?: throw FlowException("Did not find a transaction with the specified hash: $transactionHash")
214-
}
215-
216-
/**
217-
* Finds a recorded transaction in the vault for the specified transaction hash.
218-
*
219-
* @param stateRef The state reference of the transaction to find.
220-
* @return Returns a [SignedTransaction] for the specified transaction hash.
221-
* @throws FlowException If a signed Transaction cannot be found for the specified transaction hash.
222-
*
223-
*/
224-
@Suspendable
225-
fun FlowLogic<*>.findTransaction(stateRef: StateRef): SignedTransaction {
226-
return findTransaction(stateRef.txhash)
227-
}
228-
229-
/**
230-
* Finds a recorded transaction in the vault for the specified transaction hash.
231-
*
232-
* @param stateAndRef The state and reference of the transaction to find.
233-
* @return Returns a [SignedTransaction] for the specified transaction hash.
234-
* @throws FlowException If a signed Transaction cannot be found for the specified transaction hash.
235-
*
236-
*/
237-
@Suspendable
238-
fun FlowLogic<*>.findTransaction(stateAndRef: StateAndRef<*>): SignedTransaction {
239-
return findTransaction(stateAndRef.ref)
240-
}

0 commit comments

Comments
 (0)