1
- package net.corda.ledger.utxo.transaction.verifier
1
+ package net.corda.ledger.libs.verification.impl
2
2
3
- import io.micrometer.core.instrument.Timer
4
3
import net.corda.crypto.core.SecureHashImpl
5
- import net.corda.ledger.common.testkit.anotherPublicKeyExample
6
- import net.corda.ledger.common.testkit.publicKeyExample
7
- import net.corda.ledger.utxo.data.state.StateAndRefImpl
8
- import net.corda.ledger.utxo.data.transaction.UtxoLedgerTransactionImpl
9
- import net.corda.ledger.utxo.testkit.anotherNotaryX500Name
10
- import net.corda.ledger.utxo.testkit.notaryX500Name
11
4
import net.corda.v5.base.types.MemberX500Name
12
- import net.corda.v5.crypto.SecureHash
13
5
import net.corda.v5.ledger.common.transaction.TransactionMetadata
14
6
import net.corda.v5.ledger.utxo.Command
15
- import net.corda.v5.ledger.utxo.Contract
16
7
import net.corda.v5.ledger.utxo.ContractState
17
- import net.corda.v5.ledger.utxo.ContractVerificationException
18
- import net.corda.v5.ledger.utxo.EncumbranceGroup
19
- import net.corda.v5.ledger.utxo.StateAndRef
20
8
import net.corda.v5.ledger.utxo.StateRef
21
9
import net.corda.v5.ledger.utxo.TransactionState
22
10
import net.corda.v5.ledger.utxo.transaction.UtxoLedgerTransaction
23
11
import org.assertj.core.api.Assertions.assertThatThrownBy
24
12
import org.junit.jupiter.api.BeforeEach
25
13
import org.junit.jupiter.api.Test
26
14
import org.junit.jupiter.api.assertDoesNotThrow
27
- import org.mockito.kotlin.any
28
- import org.mockito.kotlin.argumentCaptor
29
- import org.mockito.kotlin.doAnswer
30
- import org.mockito.kotlin.doReturn
31
15
import org.mockito.kotlin.mock
32
16
import org.mockito.kotlin.whenever
17
+ import java.security.KeyPair
18
+ import java.security.KeyPairGenerator
33
19
import java.security.PublicKey
34
- import java.util.concurrent.Callable
20
+ import java.security.spec.ECGenParameterSpec
35
21
36
- class UtxoLedgerTransactionVerifierTest {
22
+ class UtxoLedgerTransactionVerifierImplTest {
37
23
38
24
private val transaction = mock<UtxoLedgerTransaction >()
39
25
private val signatory = mock<PublicKey >()
@@ -43,23 +29,26 @@ class UtxoLedgerTransactionVerifierTest {
43
29
private val inputTransactionState = mock<TransactionState <ContractState >>()
44
30
private val referenceTransactionState = mock<TransactionState <ContractState >>()
45
31
private val metadata = mock<TransactionMetadata >()
46
- private val injectionService = mock< (Contract ) -> Unit > ()
47
- private val callable = argumentCaptor<Callable <Any >>()
48
- private val timer = mock<Timer > {
49
- on { recordCallable(callable.capture()) } doAnswer { callable.lastValue.call() }
32
+
33
+ private val verifier = UtxoLedgerTransactionVerifierImpl (transaction) {
34
+ // NO-OP contract verification
50
35
}
51
- private val metricFactory = mock<ContractVerificationMetricFactory > {
52
- on { getContractVerificationTimeMetric() } doReturn timer
53
- on { getContractVerificationContractCountMetric() } doReturn mock()
54
- on { getContractVerificationContractTime(any()) } doReturn timer
36
+
37
+ private companion object {
38
+ val notaryX500Name = MemberX500Name .parse(" O=ExampleNotaryService, L=London, C=GB" )
39
+ val anotherNotaryX500Name = MemberX500Name .parse(" O=AnotherExampleNotaryService, L=London, C=GB" )
40
+
41
+ val kpg = KeyPairGenerator .getInstance(" EC" )
42
+ .apply { initialize(ECGenParameterSpec (" secp256r1" )) }
43
+
44
+ val keyPairExample: KeyPair = kpg.generateKeyPair()
45
+ val publicKeyExample: PublicKey = keyPairExample.public
46
+ val anotherPublicKeyExample: PublicKey = kpg
47
+ .generateKeyPair().public
55
48
}
56
- private val verifier = UtxoLedgerTransactionVerifier ({ transaction }, transaction, injectionService, metricFactory)
57
49
58
50
@BeforeEach
59
51
fun beforeEach () {
60
- whenever(metadata.getLedgerModel()).thenReturn(UtxoLedgerTransactionImpl ::class .java.name)
61
- whenever(metadata.getTransactionSubtype()).thenReturn(" GENERAL" )
62
-
63
52
whenever(transaction.id).thenReturn(SecureHashImpl (" SHA" , byteArrayOf(1 , 1 , 1 , 1 )))
64
53
whenever(transaction.signatories).thenReturn(listOf (signatory))
65
54
whenever(transaction.inputStateRefs).thenReturn(listOf (stateRef))
@@ -169,7 +158,7 @@ class UtxoLedgerTransactionVerifierTest {
169
158
whenever(referenceTransactionState.notaryName).thenReturn(anotherNotaryX500Name)
170
159
assertThatThrownBy { verifier.verify() }
171
160
.isExactlyInstanceOf(IllegalStateException ::class .java)
172
- .hasMessageContaining(" Input and reference states' notaries need to be the same as the UtxoLedgerTransaction 's notary" )
161
+ .hasMessageContaining(" Input and reference states' notaries need to be the same as the transaction 's notary" )
173
162
}
174
163
175
164
@Test
@@ -183,58 +172,4 @@ class UtxoLedgerTransactionVerifierTest {
183
172
fun `throws an exception if input states are older than output states` () {
184
173
// TODO CORE-8957 (needs to access the previous transactions from the backchain somehow)
185
174
}
186
-
187
- @Test
188
- fun `catches exceptions from contract verification and outputs them as failure reasons` () {
189
- val validContractAState = stateAndRef<MyInvalidContractA >(
190
- SecureHashImpl (" SHA" , byteArrayOf(1 , 1 , 1 , 1 )),
191
- 0
192
- )
193
- whenever(transaction.inputStateAndRefs).thenReturn(listOf (validContractAState))
194
- whenever(transaction.outputStateAndRefs).thenReturn(emptyList())
195
- assertThatThrownBy { verifier.verify() }
196
- .isExactlyInstanceOf(ContractVerificationException ::class .java)
197
- .hasMessageContainingAll(" I have failed" )
198
- }
199
-
200
- private inline fun <reified C : Contract > stateAndRef (
201
- transactionId : SecureHash ,
202
- index : Int
203
- ): StateAndRef <UtxoLedgerTransactionContractVerifierTest .MyState > {
204
- val state = UtxoLedgerTransactionContractVerifierTest .MyState ()
205
- return StateAndRefImpl (
206
- object : TransactionState <UtxoLedgerTransactionContractVerifierTest .MyState > {
207
- override fun getContractState (): UtxoLedgerTransactionContractVerifierTest .MyState {
208
- return state
209
- }
210
-
211
- override fun getContractStateType (): Class <UtxoLedgerTransactionContractVerifierTest .MyState > {
212
- return state.javaClass
213
- }
214
-
215
- override fun getContractType (): Class <out Contract > {
216
- return C ::class .java
217
- }
218
-
219
- override fun getNotaryName (): MemberX500Name {
220
- return notaryX500Name
221
- }
222
-
223
- override fun getNotaryKey (): PublicKey {
224
- return publicKeyExample
225
- }
226
-
227
- override fun getEncumbranceGroup (): EncumbranceGroup ? {
228
- return null
229
- }
230
- },
231
- StateRef (transactionId, index)
232
- )
233
- }
234
-
235
- class MyInvalidContractA : Contract {
236
- override fun verify (transaction : UtxoLedgerTransaction ) {
237
- throw IllegalStateException (" I have failed" )
238
- }
239
- }
240
175
}
0 commit comments