mirror of
https://github.com/corda/corda.git
synced 2025-05-31 22:50:53 +00:00
ENT-12709: Replace uses of assert
with correct assertion methods (#7902)
The Kotlin `assert` is only active if the `-ea` JVM flag is specified, which it isn't. Replaced all uses with the correct assertj assertion.
This commit is contained in:
parent
781aaba649
commit
df8f4fa3e9
@ -36,6 +36,7 @@ import net.corda.testing.driver.driver
|
||||
import net.corda.testing.node.User
|
||||
import net.corda.testing.node.internal.findCordapp
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
@ -411,7 +412,7 @@ class VaultObserverExceptionTest {
|
||||
testControlFuture.complete(true)
|
||||
}
|
||||
startNode(providedName = ALICE_NAME, rpcUsers = listOf(aliceUser), startInSameProcess = true).getOrThrow()
|
||||
assert(testControlFuture.getOrThrow(waitForFlowDuration))
|
||||
assertThat(testControlFuture.getOrThrow(waitForFlowDuration)).isTrue()
|
||||
} else {
|
||||
throw IllegalStateException("Out of process node is still up and running!")
|
||||
}
|
||||
@ -900,4 +901,4 @@ class VaultObserverExceptionTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ class NetworkMapUpdaterTest {
|
||||
Thread.sleep(2L * cacheExpiryMs)
|
||||
val newHash = newParameters.serialize().hash
|
||||
val updateFile = baseDir / NETWORK_PARAMS_UPDATE_FILE_NAME
|
||||
assert(!updateFile.exists()) { "network parameters should not be auto accepted" }
|
||||
assertThat(updateFile).describedAs("network parameters should not be auto accepted").doesNotExist()
|
||||
updater!!.acceptNewNetworkParameters(newHash) { it.serialize().sign(ourKeyPair) }
|
||||
verify(networkParametersStorage, times(1)).saveParameters(any())
|
||||
val signedNetworkParams = updateFile.readObject<SignedNetworkParameters>()
|
||||
@ -398,7 +398,7 @@ class NetworkMapUpdaterTest {
|
||||
//TODO: Remove sleep in unit test.
|
||||
Thread.sleep(2L * cacheExpiryMs)
|
||||
val updateFile = baseDir / NETWORK_PARAMS_UPDATE_FILE_NAME
|
||||
assert(!updateFile.exists()) { "network parameters should not be auto accepted" }
|
||||
assertThat(updateFile).describedAs("network parameters should not be auto accepted").doesNotExist()
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
@ -412,7 +412,7 @@ class NetworkMapUpdaterTest {
|
||||
//TODO: Remove sleep in unit test.
|
||||
Thread.sleep(2L * cacheExpiryMs)
|
||||
val updateFile = baseDir / NETWORK_PARAMS_UPDATE_FILE_NAME
|
||||
assert(!updateFile.exists()) { "network parameters should not be auto accepted" }
|
||||
assertThat(updateFile).describedAs("network parameters should not be auto accepted").doesNotExist()
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
@ -592,16 +592,16 @@ class NetworkMapUpdaterTest {
|
||||
|
||||
//TODO: Remove sleep in unit test.
|
||||
Thread.sleep(2L * cacheExpiryMs)
|
||||
assert(networkMapCache.allNodeHashes.size == 1)
|
||||
assert(networkMapCache.allNodeHashes.first() == signedNodeInfo1.raw.hash)
|
||||
assertThat(networkMapCache.allNodeHashes).hasSize(1)
|
||||
assertThat(networkMapCache.allNodeHashes.first()).isEqualTo(signedNodeInfo1.raw.hash)
|
||||
verify(networkMapCache, times(1)).addOrUpdateNodes(listOf(signedNodeInfo1.verified()))
|
||||
networkMapClient.publish(signedNodeInfo2)
|
||||
Thread.sleep(2L * cacheExpiryMs)
|
||||
advanceTime()
|
||||
|
||||
verify(networkMapCache, times(1)).addOrUpdateNodes(listOf(signedNodeInfo1.verified()))
|
||||
assert(networkMapCache.allNodeHashes.size == 1)
|
||||
assert(networkMapCache.allNodeHashes.first() == signedNodeInfo2.raw.hash)
|
||||
assertThat(networkMapCache.allNodeHashes).hasSize(1)
|
||||
assertThat(networkMapCache.allNodeHashes.first()).isEqualTo(signedNodeInfo2.raw.hash)
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
|
@ -44,14 +44,13 @@ import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.time.Clock
|
||||
import java.util.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
internal fun CheckpointStorage.checkpoints(): List<Checkpoint.Serialized> {
|
||||
return getCheckpoints().use {
|
||||
it.map { it.second }.toList()
|
||||
return getCheckpoints().use { stream ->
|
||||
stream.map { it.second }.toList()
|
||||
}
|
||||
}
|
||||
|
||||
@ -454,9 +453,8 @@ class DBCheckpointStorageTests {
|
||||
val deserializedException = exceptionDetails.value?.let { SerializedBytes<Any>(it) }?.deserialize(context = SerializationDefaults.STORAGE_CONTEXT)
|
||||
// IllegalStateException does not implement [CordaThrowable] therefore gets deserialized as a [CordaRuntimeException]
|
||||
assertTrue(deserializedException is CordaRuntimeException)
|
||||
val cordaRuntimeException = deserializedException
|
||||
assertEquals(IllegalStateException::class.java.name, cordaRuntimeException.originalExceptionClassName)
|
||||
assertEquals("I am a naughty exception", cordaRuntimeException.originalMessage!!)
|
||||
assertEquals(IllegalStateException::class.java.name, deserializedException.originalExceptionClassName)
|
||||
assertEquals("I am a naughty exception", deserializedException.originalMessage!!)
|
||||
}
|
||||
}
|
||||
|
||||
@ -624,12 +622,12 @@ class DBCheckpointStorageTests {
|
||||
}
|
||||
}
|
||||
|
||||
private fun iterationsBasedOnLineSeparatorLength() = when {
|
||||
System.getProperty("line.separator").length == 1 -> // Linux or Mac
|
||||
78
|
||||
System.getProperty("line.separator").length == 2 -> // Windows
|
||||
75
|
||||
else -> throw IllegalStateException("Unknown line.separator")
|
||||
private fun iterationsBasedOnLineSeparatorLength(): Int {
|
||||
return when (System.lineSeparator().length) {
|
||||
1 -> 78 // Linux or Mac
|
||||
2 -> 75 // Windows
|
||||
else -> throw IllegalStateException("Unknown line.separator")
|
||||
}
|
||||
}
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
@ -720,7 +718,7 @@ class DBCheckpointStorageTests {
|
||||
|
||||
database.transaction {
|
||||
val dbFlowCheckpoint= checkpointStorage.getDBCheckpoint(id)
|
||||
assert(dbFlowCheckpoint!!.blob != null)
|
||||
assertThat(dbFlowCheckpoint!!.blob).isNotNull
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ import net.corda.testing.core.dummyCommand
|
||||
import net.corda.testing.core.singleIdentity
|
||||
import net.corda.testing.node.MockNetworkNotarySpec
|
||||
import net.corda.testing.node.internal.*
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Assume
|
||||
import org.junit.Before
|
||||
@ -144,14 +145,14 @@ class NotaryWhitelistTests(
|
||||
val ex = assertFailsWith(NotaryException::class) {
|
||||
future.getOrThrow()
|
||||
}
|
||||
assert(ex.error is NotaryError.TransactionInvalid)
|
||||
assertThat(ex.error).isInstanceOf(NotaryError.TransactionInvalid::class.java)
|
||||
assertEquals(validStx.id, ex.txId)
|
||||
}
|
||||
|
||||
private fun removeOldNotary(parameters: NetworkParameters): NetworkParameters {
|
||||
val newParameters = parameters.copy(notaries = parameters.notaries.drop(1))
|
||||
assert(newParameters.notaries.none { it.identity == oldNotary })
|
||||
assert(newParameters.notaries.any { it.identity == newNotary })
|
||||
assertThat(newParameters.notaries).noneMatch { it.identity == oldNotary }
|
||||
assertThat(newParameters.notaries).anyMatch { it.identity == newNotary }
|
||||
return newParameters
|
||||
}
|
||||
|
||||
@ -202,7 +203,7 @@ class NotaryWhitelistTests(
|
||||
val ex = assertFailsWith(NotaryException::class) {
|
||||
future.getOrThrow()
|
||||
}
|
||||
assert(ex.error is NotaryError.TransactionInvalid)
|
||||
assertThat(ex.error).isInstanceOf(NotaryError.TransactionInvalid::class.java)
|
||||
assertEquals(validStx.id, ex.txId)
|
||||
}
|
||||
|
||||
@ -216,7 +217,7 @@ class NotaryWhitelistTests(
|
||||
return fakeStx.tx.outRef(0)
|
||||
}
|
||||
|
||||
/** Changes the notary service to [notary]. Does not actually communicate with a notary. */
|
||||
/** Changes the notary service to [fakeNotaryParty]. Does not actually communicate with a notary. */
|
||||
private fun changeNotary(inputState: StateAndRef<DummyContract.State>, fakeNotaryParty: Party, fakeNotaryKeyPair: KeyPair): NotaryChangeLedgerTransaction {
|
||||
val notaryChangeTx = NotaryChangeTransactionBuilder(
|
||||
listOf(inputState.ref),
|
||||
@ -254,4 +255,4 @@ class NotaryWhitelistTests(
|
||||
val data = SignableData(fakeStx.id, metadata)
|
||||
return fakeNotaryKeyPair.sign(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,14 @@
|
||||
package net.corda.node.services.transactions
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.contracts.BelongsToContract
|
||||
import net.corda.core.contracts.Command
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.contracts.LinearPointer
|
||||
import net.corda.core.contracts.LinearState
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.StatePointer
|
||||
import net.corda.core.contracts.StaticPointer
|
||||
import net.corda.core.contracts.UniqueIdentifier
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.node.NotaryInfo
|
||||
@ -12,6 +20,7 @@ import net.corda.testing.core.SerializationEnvironmentRule
|
||||
import net.corda.testing.core.TestIdentity
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.makeTestIdentityService
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
@ -79,7 +88,7 @@ class ResolveStatePointersTest {
|
||||
}
|
||||
|
||||
// Check the StateRef for the pointed-to state is not added as a reference.
|
||||
assert(tx.referenceStates().none { it == stateAndRef.ref })
|
||||
assertThat(tx.referenceStates()).noneMatch { it == stateAndRef.ref }
|
||||
|
||||
// Resolve the StateRef to the actual state.
|
||||
val ltx = tx.toLedgerTransaction(services)
|
||||
@ -119,7 +128,7 @@ class ResolveStatePointersTest {
|
||||
}
|
||||
|
||||
// Check the StateRef for the pointed-to state is not added as a reference.
|
||||
assert(tx.referenceStates().none { it == stateAndRef.ref })
|
||||
assertThat(tx.referenceStates()).noneMatch { it == stateAndRef.ref }
|
||||
|
||||
// Resolve the StateRef to the actual state.
|
||||
val ltx = tx.toLedgerTransaction(services)
|
||||
@ -223,4 +232,4 @@ class ResolveStatePointersTest {
|
||||
val foo = ltx.outputs.single().data as Foo<Bar>
|
||||
assertEquals(stateAndRef, foo.baz.resolve(ltx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package net.corda.node.services.transactions
|
||||
|
||||
import com.codahale.metrics.MetricRegistry
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TimeWindow
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.DigestService
|
||||
@ -14,9 +16,12 @@ import net.corda.core.crypto.randomHash
|
||||
import net.corda.core.flows.NotarisationRequestSignature
|
||||
import net.corda.core.flows.NotaryError
|
||||
import net.corda.core.flows.StateConsumptionDetails
|
||||
import net.corda.core.flows.StateConsumptionDetails.ConsumedStateType.INPUT_STATE
|
||||
import net.corda.core.flows.StateConsumptionDetails.ConsumedStateType.REFERENCE_INPUT_STATE
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.HashAgility
|
||||
import net.corda.core.internal.notary.UniquenessProvider
|
||||
import net.corda.core.internal.notary.UniquenessProvider.Result
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.core.utilities.minutes
|
||||
import net.corda.coretesting.internal.configureTestSSL
|
||||
@ -41,6 +46,7 @@ import net.corda.testing.node.MockServices.Companion.makeTestDataSourcePropertie
|
||||
import net.corda.testing.node.TestClock
|
||||
import net.corda.testing.node.internal.MockKeyManagementService
|
||||
import net.corda.testing.node.makeTestIdentityService
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
@ -49,7 +55,6 @@ import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
import java.security.KeyPair
|
||||
import java.time.Clock
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(Parameterized::class)
|
||||
class UniquenessProviderTests(
|
||||
@ -58,18 +63,19 @@ class UniquenessProviderTests(
|
||||
) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@Parameterized.Parameters
|
||||
fun data(): Collection<Array<Any>> = listOf(
|
||||
arrayOf(JPAUniquenessProviderFactory(DigestService.sha2_256), DigestService.sha2_256),
|
||||
arrayOf(RaftUniquenessProviderFactory(), DigestService.sha2_256)
|
||||
// arrayOf(JPAUniquenessProviderFactory(DigestService.sha2_512), DigestService.sha2_512),
|
||||
// arrayOf(RaftUniquenessProviderFactory(), DigestService.sha2_512)
|
||||
)
|
||||
@Parameterized.Parameters(name = "{0} {1}")
|
||||
fun data(): Collection<Array<Any>> {
|
||||
return listOf(
|
||||
arrayOf(JPAUniquenessProviderFactory(DigestService.sha2_256), DigestService.sha2_256),
|
||||
arrayOf(RaftUniquenessProviderFactory(), DigestService.sha2_256)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val testSerialization = SerializationEnvironmentRule(inheritable = true)
|
||||
|
||||
private val identity = TestIdentity(CordaX500Name("MegaCorp", "London", "GB")).party
|
||||
private val txID = digestService.randomHash()
|
||||
private val requestSignature = NotarisationRequestSignature(DigitalSignature.WithKey(NullKeys.NullPublicKey, ByteArray(32)), 0)
|
||||
@ -112,11 +118,7 @@ class UniquenessProviderTests(
|
||||
val timeWindow = TimeWindow.between(
|
||||
Clock.systemUTC().instant().plus(30.minutes),
|
||||
Clock.systemUTC().instant().plus(60.minutes))
|
||||
val result = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, timeWindow).get()
|
||||
assert(result is UniquenessProvider.Result.Failure)
|
||||
val error = (result as UniquenessProvider.Result.Failure).error as NotaryError.TimeWindowInvalid
|
||||
assertEquals(timeWindow, error.txTimeWindow)
|
||||
expectInvalidTimeWindow(emptyList(), firstTxId, timeWindow)
|
||||
|
||||
// Once time window behaviour has changed, we should add an additional test case here to check
|
||||
// that retry within time window still fails. We can't do that now because currently it will
|
||||
@ -124,51 +126,34 @@ class UniquenessProviderTests(
|
||||
|
||||
// Retry still fails after advancing past time window
|
||||
testClock.advanceBy(90.minutes)
|
||||
val result2 = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, timeWindow).get()
|
||||
assert(result2 is UniquenessProvider.Result.Failure)
|
||||
val error2 = (result2 as UniquenessProvider.Result.Failure).error as NotaryError.TimeWindowInvalid
|
||||
assertEquals(timeWindow, error2.txTimeWindow)
|
||||
expectInvalidTimeWindow(emptyList(), firstTxId, timeWindow)
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `commits transaction within time window`() {
|
||||
val firstTxId = digestService.randomHash()
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().plus(30.minutes))
|
||||
val result = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, timeWindow).get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
|
||||
expectCommitSuccess(emptyList(), firstTxId, timeWindow)
|
||||
|
||||
// Retry is successful whilst still within time window
|
||||
testClock.advanceBy(10.minutes)
|
||||
val result2 = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, timeWindow).get()
|
||||
assert(result2 is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(emptyList(), firstTxId, timeWindow)
|
||||
|
||||
// Retry is successful after time window has expired
|
||||
testClock.advanceBy(80.minutes)
|
||||
val result3 = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, timeWindow).get()
|
||||
assert(result3 is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(emptyList(), firstTxId, timeWindow)
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `rejects transaction after time window has expired`() {
|
||||
val firstTxId = digestService.randomHash()
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().minus(30.minutes))
|
||||
val result = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, timeWindow).get()
|
||||
assert(result is UniquenessProvider.Result.Failure)
|
||||
val error = (result as UniquenessProvider.Result.Failure).error as NotaryError.TimeWindowInvalid
|
||||
assertEquals(timeWindow, error.txTimeWindow)
|
||||
expectInvalidTimeWindow(emptyList(), firstTxId, timeWindow)
|
||||
|
||||
// Retry still fails at a later time
|
||||
testClock.advanceBy(10.minutes)
|
||||
val result2 = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, timeWindow).get()
|
||||
assert(result2 is UniquenessProvider.Result.Failure)
|
||||
val error2 = (result2 as UniquenessProvider.Result.Failure).error as NotaryError.TimeWindowInvalid
|
||||
assertEquals(timeWindow, error2.txTimeWindow)
|
||||
expectInvalidTimeWindow(emptyList(), firstTxId, timeWindow)
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
@ -178,56 +163,42 @@ class UniquenessProviderTests(
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().plus(30.minutes))
|
||||
val invalidTimeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().minus(30.minutes))
|
||||
|
||||
val validFuture1 = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, timeWindow)
|
||||
val validFuture2 = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, timeWindow)
|
||||
val invalidFuture1 = uniquenessProvider.commit(
|
||||
emptyList(), secondTxId, identity, requestSignature, invalidTimeWindow)
|
||||
val invalidFuture2 = uniquenessProvider.commit(
|
||||
emptyList(), secondTxId, identity, requestSignature, invalidTimeWindow)
|
||||
val validFuture1 = commit(emptyList(), firstTxId, timeWindow)
|
||||
val validFuture2 = commit(emptyList(), firstTxId, timeWindow)
|
||||
val invalidFuture1 = commit(emptyList(), secondTxId, invalidTimeWindow)
|
||||
val invalidFuture2 = commit(emptyList(), secondTxId, invalidTimeWindow)
|
||||
|
||||
// Ensure that transactions are processed correctly and duplicates get the same responses to original
|
||||
assert(validFuture1.get() is UniquenessProvider.Result.Success)
|
||||
assert(validFuture2.get() is UniquenessProvider.Result.Success)
|
||||
assert(invalidFuture1.get() is UniquenessProvider.Result.Failure)
|
||||
assert(invalidFuture2.get() is UniquenessProvider.Result.Failure)
|
||||
assertThat(validFuture1.get()).isInstanceOf(Result.Success::class.java)
|
||||
assertThat(validFuture2.get()).isInstanceOf(Result.Success::class.java)
|
||||
assertThat(invalidFuture1.get()).isInstanceOf(Result.Failure::class.java)
|
||||
assertThat(invalidFuture2.get()).isInstanceOf(Result.Failure::class.java)
|
||||
}
|
||||
|
||||
/* Group B: only reference states */
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `commits transaction with unused reference states`() {
|
||||
fun `commits transaction with unused reference states`() {
|
||||
val firstTxId = digestService.randomHash()
|
||||
val referenceState = generateStateRef()
|
||||
|
||||
val result = uniquenessProvider.commit(emptyList(), firstTxId, identity, requestSignature, references = listOf(referenceState))
|
||||
.get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(emptyList(), firstTxId, references = listOf(referenceState))
|
||||
|
||||
// Idempotency: can re-notarise successfully.
|
||||
val result2 = uniquenessProvider.commit(emptyList(), firstTxId, identity, requestSignature, references = listOf(referenceState))
|
||||
.get()
|
||||
assert(result2 is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(emptyList(), firstTxId, references = listOf(referenceState))
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `rejects transaction with previously used reference states`() {
|
||||
fun `rejects transaction with previously used reference states`() {
|
||||
val firstTxId = digestService.randomHash()
|
||||
val referenceState = generateStateRef()
|
||||
|
||||
val result = uniquenessProvider.commit(listOf(referenceState), firstTxId, identity, requestSignature, references = emptyList())
|
||||
.get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(referenceState), firstTxId, references = emptyList())
|
||||
|
||||
// Transaction referencing the spent sate fails.
|
||||
val secondTxId = digestService.randomHash()
|
||||
val result2 = uniquenessProvider.commit(emptyList(), secondTxId, identity, requestSignature, references = listOf(referenceState))
|
||||
.get()
|
||||
val error = (result2 as UniquenessProvider.Result.Failure).error as NotaryError.Conflict
|
||||
val conflictCause = error.consumedStates[referenceState]!!
|
||||
assertEquals(conflictCause.hashOfTransactionId, firstTxId.reHash(), "${conflictCause.hashOfTransactionId} != ${firstTxId.reHash()}")
|
||||
assertEquals(StateConsumptionDetails.ConsumedStateType.REFERENCE_INPUT_STATE, conflictCause.type)
|
||||
val consumedStates = expectConflict(emptyList(), secondTxId, references = listOf(referenceState))
|
||||
assertThat(consumedStates[referenceState]).isEqualTo(StateConsumptionDetails(firstTxId.reHash(), REFERENCE_INPUT_STATE))
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
@ -235,23 +206,14 @@ class UniquenessProviderTests(
|
||||
val firstTxId = digestService.randomHash()
|
||||
val referenceState = generateStateRef()
|
||||
|
||||
val result = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, references = listOf(referenceState))
|
||||
.get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(emptyList(), firstTxId, references = listOf(referenceState))
|
||||
|
||||
// Spend reference state
|
||||
val secondTxId = digestService.randomHash()
|
||||
val result2 = uniquenessProvider.commit(
|
||||
listOf(referenceState), secondTxId, identity, requestSignature, references = emptyList())
|
||||
.get()
|
||||
assert(result2 is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(referenceState), secondTxId, references = emptyList())
|
||||
|
||||
// Retry referencing the now spent state still succeeds
|
||||
val result3 = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, references = listOf(referenceState))
|
||||
.get()
|
||||
assert(result3 is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(emptyList(), firstTxId, references = listOf(referenceState))
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
@ -260,128 +222,97 @@ class UniquenessProviderTests(
|
||||
val secondTxId = digestService.randomHash()
|
||||
val referenceState = generateStateRef()
|
||||
|
||||
val validFuture3 = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, references = listOf(referenceState))
|
||||
val validFuture4 = uniquenessProvider.commit(
|
||||
emptyList(), firstTxId, identity, requestSignature, references = listOf(referenceState))
|
||||
val validFuture1 = uniquenessProvider.commit(
|
||||
emptyList(), secondTxId, identity, requestSignature, references = listOf(referenceState))
|
||||
val validFuture2 = uniquenessProvider.commit(
|
||||
emptyList(), secondTxId, identity, requestSignature, references = listOf(referenceState))
|
||||
val validFuture3 = commit(emptyList(), firstTxId, references = listOf(referenceState))
|
||||
val validFuture4 = commit(emptyList(), firstTxId, references = listOf(referenceState))
|
||||
val validFuture1 = commit(emptyList(), secondTxId, references = listOf(referenceState))
|
||||
val validFuture2 = commit(emptyList(), secondTxId, references = listOf(referenceState))
|
||||
|
||||
// Ensure that transactions are processed correctly and duplicates get the same responses to original
|
||||
assert(validFuture1.get() is UniquenessProvider.Result.Success)
|
||||
assert(validFuture2.get() is UniquenessProvider.Result.Success)
|
||||
assert(validFuture3.get() is UniquenessProvider.Result.Success)
|
||||
assert(validFuture4.get() is UniquenessProvider.Result.Success)
|
||||
assertThat(validFuture1.get()).isInstanceOf(Result.Success::class.java)
|
||||
assertThat(validFuture2.get()).isInstanceOf(Result.Success::class.java)
|
||||
assertThat(validFuture3.get()).isInstanceOf(Result.Success::class.java)
|
||||
assertThat(validFuture4.get()).isInstanceOf(Result.Success::class.java)
|
||||
}
|
||||
|
||||
/* Group C: reference states & time window */
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `commits transaction with unused reference states and valid time window`() {
|
||||
fun `commits transaction with unused reference states and valid time window`() {
|
||||
val firstTxId = digestService.randomHash()
|
||||
val referenceState = generateStateRef()
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().plus(30.minutes))
|
||||
|
||||
val result = uniquenessProvider.commit(emptyList(), firstTxId, identity, requestSignature, timeWindow, references = listOf(referenceState))
|
||||
.get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(emptyList(), firstTxId, timeWindow, references = listOf(referenceState))
|
||||
|
||||
// The reference state gets consumed.
|
||||
val result2 = uniquenessProvider.commit(listOf(referenceState), digestService.randomHash(), identity, requestSignature, timeWindow)
|
||||
.get()
|
||||
assert(result2 is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(referenceState), digestService.randomHash(), timeWindow)
|
||||
|
||||
// Idempotency: can re-notarise successfully.
|
||||
testClock.advanceBy(90.minutes)
|
||||
val result3 = uniquenessProvider.commit(emptyList(), firstTxId, identity, requestSignature, timeWindow, references = listOf(referenceState))
|
||||
.get()
|
||||
assert(result3 is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(emptyList(), firstTxId, timeWindow, references = listOf(referenceState))
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `rejects transaction with unused reference states and invalid time window`() {
|
||||
fun `rejects transaction with unused reference states and invalid time window`() {
|
||||
val firstTxId = digestService.randomHash()
|
||||
val referenceState = generateStateRef()
|
||||
val invalidTimeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().minus(30.minutes))
|
||||
|
||||
val result = uniquenessProvider.commit(emptyList(), firstTxId, identity, requestSignature, invalidTimeWindow, references = listOf(referenceState))
|
||||
.get()
|
||||
val error = (result as UniquenessProvider.Result.Failure).error as NotaryError.TimeWindowInvalid
|
||||
assertEquals(invalidTimeWindow, error.txTimeWindow)
|
||||
expectInvalidTimeWindow(emptyList(), firstTxId, invalidTimeWindow, references = listOf(referenceState))
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `rejects transaction with previously used reference states and valid time window`() {
|
||||
fun `rejects transaction with previously used reference states and valid time window`() {
|
||||
val firstTxId = digestService.randomHash()
|
||||
val referenceState = generateStateRef()
|
||||
|
||||
val result = uniquenessProvider.commit(listOf(referenceState), firstTxId, identity, requestSignature, references = emptyList())
|
||||
.get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(referenceState), firstTxId, references = emptyList())
|
||||
|
||||
// Transaction referencing the spent sate fails.
|
||||
val secondTxId = digestService.randomHash()
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().plus(30.minutes))
|
||||
val result2 = uniquenessProvider.commit(emptyList(), secondTxId, identity, requestSignature, timeWindow, references = listOf(referenceState))
|
||||
.get()
|
||||
val error = (result2 as UniquenessProvider.Result.Failure).error as NotaryError.Conflict
|
||||
val conflictCause = error.consumedStates[referenceState]!!
|
||||
assertEquals(conflictCause.hashOfTransactionId, firstTxId.reHash())
|
||||
assertEquals(StateConsumptionDetails.ConsumedStateType.REFERENCE_INPUT_STATE, conflictCause.type)
|
||||
val consumedStates = expectConflict(emptyList(), secondTxId, timeWindow, references = listOf(referenceState))
|
||||
assertThat(consumedStates[referenceState]).isEqualTo(StateConsumptionDetails(firstTxId.reHash(), REFERENCE_INPUT_STATE))
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `rejects transaction with previously used reference states and invalid time window`() {
|
||||
fun `rejects transaction with previously used reference states and invalid time window`() {
|
||||
val firstTxId = digestService.randomHash()
|
||||
val referenceState = generateStateRef()
|
||||
|
||||
val result = uniquenessProvider.commit(listOf(referenceState), firstTxId, identity, requestSignature, references = emptyList())
|
||||
.get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(referenceState), firstTxId, references = emptyList())
|
||||
|
||||
// Transaction referencing the spent sate fails.
|
||||
val secondTxId = digestService.randomHash()
|
||||
val invalidTimeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().minus(30.minutes))
|
||||
val result2 = uniquenessProvider.commit(emptyList(), secondTxId, identity, requestSignature, invalidTimeWindow, references = listOf(referenceState))
|
||||
.get()
|
||||
val error = (result2 as UniquenessProvider.Result.Failure).error as NotaryError.Conflict
|
||||
val conflictCause = error.consumedStates[referenceState]!!
|
||||
assertEquals(conflictCause.hashOfTransactionId, firstTxId.reHash())
|
||||
assertEquals(StateConsumptionDetails.ConsumedStateType.REFERENCE_INPUT_STATE, conflictCause.type)
|
||||
val consumedStates = expectConflict(emptyList(), secondTxId, invalidTimeWindow, references = listOf(referenceState))
|
||||
assertThat(consumedStates[referenceState]).isEqualTo(StateConsumptionDetails(firstTxId.reHash(), REFERENCE_INPUT_STATE))
|
||||
}
|
||||
|
||||
/* Group D: only input states */
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `commits transaction with unused inputs`() {
|
||||
fun `commits transaction with unused inputs`() {
|
||||
val inputState = generateStateRef()
|
||||
|
||||
val result = uniquenessProvider.commit(listOf(inputState), txID, identity, requestSignature).get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(inputState), txID)
|
||||
|
||||
// Idempotency: can re-notarise successfully.
|
||||
val result2 = uniquenessProvider.commit(listOf(inputState), txID, identity, requestSignature).get()
|
||||
assert(result2 is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(inputState), txID)
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `rejects transaction with previously used inputs`() {
|
||||
fun `rejects transaction with previously used inputs`() {
|
||||
val inputState = generateStateRef()
|
||||
|
||||
val inputs = listOf(inputState)
|
||||
val firstTxId = txID
|
||||
val result = uniquenessProvider.commit(inputs, firstTxId, identity, requestSignature).get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(inputs, firstTxId)
|
||||
|
||||
val secondTxId = digestService.randomHash()
|
||||
|
||||
val response: UniquenessProvider.Result = uniquenessProvider.commit(inputs, secondTxId, identity, requestSignature).get()
|
||||
val error = (response as UniquenessProvider.Result.Failure).error as NotaryError.Conflict
|
||||
|
||||
val conflictCause = error.consumedStates[inputState]!!
|
||||
assertEquals(firstTxId.reHash(), conflictCause.hashOfTransactionId)
|
||||
val consumedStates = expectConflict(inputs, secondTxId)
|
||||
assertThat(consumedStates[inputState]).isEqualTo(StateConsumptionDetails(firstTxId.reHash(), INPUT_STATE))
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
@ -390,104 +321,82 @@ class UniquenessProviderTests(
|
||||
val secondTxId = digestService.randomHash()
|
||||
val inputState = generateStateRef()
|
||||
|
||||
val validFuture1 = uniquenessProvider.commit(
|
||||
listOf(inputState), firstTxId, identity, requestSignature)
|
||||
val validFuture2 = uniquenessProvider.commit(
|
||||
listOf(inputState), firstTxId, identity, requestSignature)
|
||||
val invalidFuture1 = uniquenessProvider.commit(
|
||||
listOf(inputState), secondTxId, identity, requestSignature)
|
||||
val invalidFuture2 = uniquenessProvider.commit(
|
||||
listOf(inputState), secondTxId, identity, requestSignature)
|
||||
val validFuture1 = commit(listOf(inputState), firstTxId)
|
||||
val validFuture2 = commit(listOf(inputState), firstTxId)
|
||||
val invalidFuture1 = commit(listOf(inputState), secondTxId)
|
||||
val invalidFuture2 = commit(listOf(inputState), secondTxId)
|
||||
|
||||
// Ensure that transactions are processed correctly and duplicates get the same responses to original
|
||||
assert(validFuture1.get() is UniquenessProvider.Result.Success)
|
||||
assert(validFuture2.get() is UniquenessProvider.Result.Success)
|
||||
assert(invalidFuture1.get() is UniquenessProvider.Result.Failure)
|
||||
assert(invalidFuture2.get() is UniquenessProvider.Result.Failure)
|
||||
assertThat(validFuture1.get()).isInstanceOf(Result.Success::class.java)
|
||||
assertThat(validFuture2.get()).isInstanceOf(Result.Success::class.java)
|
||||
assertThat(invalidFuture1.get()).isInstanceOf(Result.Failure::class.java)
|
||||
assertThat(invalidFuture2.get()).isInstanceOf(Result.Failure::class.java)
|
||||
}
|
||||
|
||||
/* Group E: input states & time window */
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `commits transaction with unused inputs and valid time window`() {
|
||||
fun `commits transaction with unused inputs and valid time window`() {
|
||||
val inputState = generateStateRef()
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().plus(30.minutes))
|
||||
|
||||
val result = uniquenessProvider.commit(listOf(inputState), txID, identity, requestSignature, timeWindow).get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(inputState), txID, timeWindow)
|
||||
|
||||
// Idempotency: can re-notarise successfully later.
|
||||
testClock.advanceBy(90.minutes)
|
||||
val result2 = uniquenessProvider.commit(listOf(inputState), txID, identity, requestSignature, timeWindow).get()
|
||||
assert(result2 is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(inputState), txID, timeWindow)
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `rejects transaction with unused inputs and invalid time window`() {
|
||||
fun `rejects transaction with unused inputs and invalid time window`() {
|
||||
val inputState = generateStateRef()
|
||||
val invalidTimeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().minus(30.minutes))
|
||||
|
||||
val result = uniquenessProvider.commit(listOf(inputState), txID, identity, requestSignature, invalidTimeWindow).get()
|
||||
val error = (result as UniquenessProvider.Result.Failure).error as NotaryError.TimeWindowInvalid
|
||||
assertEquals(invalidTimeWindow, error.txTimeWindow)
|
||||
expectInvalidTimeWindow(listOf(inputState), txID, invalidTimeWindow)
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `rejects transaction with previously used inputs and valid time window`() {
|
||||
fun `rejects transaction with previously used inputs and valid time window`() {
|
||||
val inputState = generateStateRef()
|
||||
val inputs = listOf(inputState)
|
||||
val firstTxId = txID
|
||||
val result = uniquenessProvider.commit(inputs, firstTxId, identity, requestSignature).get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(inputs, firstTxId)
|
||||
|
||||
val secondTxId = digestService.randomHash()
|
||||
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().plus(30.minutes))
|
||||
val response: UniquenessProvider.Result = uniquenessProvider.commit(inputs, secondTxId, identity, requestSignature, timeWindow)
|
||||
.get()
|
||||
val error = (response as UniquenessProvider.Result.Failure).error as NotaryError.Conflict
|
||||
|
||||
val conflictCause = error.consumedStates[inputState]!!
|
||||
assertEquals(firstTxId.reHash(), conflictCause.hashOfTransactionId)
|
||||
val consumedStates = expectConflict(inputs, secondTxId, timeWindow)
|
||||
assertThat(consumedStates[inputState]).isEqualTo(StateConsumptionDetails(firstTxId.reHash(), INPUT_STATE))
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `rejects transaction with previously used inputs and invalid time window`() {
|
||||
fun `rejects transaction with previously used inputs and invalid time window`() {
|
||||
val inputState = generateStateRef()
|
||||
val inputs = listOf(inputState)
|
||||
val firstTxId = txID
|
||||
val result = uniquenessProvider.commit(inputs, firstTxId, identity, requestSignature).get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(inputs, firstTxId)
|
||||
|
||||
val secondTxId = digestService.randomHash()
|
||||
|
||||
val invalidTimeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().minus(30.minutes))
|
||||
val response: UniquenessProvider.Result = uniquenessProvider.commit(inputs, secondTxId, identity, requestSignature, invalidTimeWindow)
|
||||
.get()
|
||||
val error = (response as UniquenessProvider.Result.Failure).error as NotaryError.Conflict
|
||||
|
||||
val conflictCause = error.consumedStates[inputState]!!
|
||||
assertEquals(firstTxId.reHash(), conflictCause.hashOfTransactionId)
|
||||
val consumedStates = expectConflict(inputs, secondTxId, invalidTimeWindow)
|
||||
assertThat(consumedStates[inputState]).isEqualTo(StateConsumptionDetails(firstTxId.reHash(), INPUT_STATE))
|
||||
}
|
||||
|
||||
/* Group F: input & reference states */
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `commits transaction with unused input & reference states`() {
|
||||
fun `commits transaction with unused input & reference states`() {
|
||||
val firstTxId = digestService.randomHash()
|
||||
val inputState = generateStateRef()
|
||||
val referenceState = generateStateRef()
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().plus(30.minutes))
|
||||
|
||||
val result = uniquenessProvider.commit(listOf(inputState), firstTxId, identity, requestSignature, timeWindow, references = listOf(referenceState))
|
||||
.get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(inputState), firstTxId, timeWindow, references = listOf(referenceState))
|
||||
|
||||
// Idempotency: can re-notarise successfully.
|
||||
testClock.advanceBy(90.minutes)
|
||||
val result2 = uniquenessProvider.commit(listOf(inputState), firstTxId, identity, requestSignature, timeWindow, references = listOf(referenceState))
|
||||
.get()
|
||||
assert(result2 is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(inputState), firstTxId, timeWindow, references = listOf(referenceState))
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
@ -497,69 +406,46 @@ class UniquenessProviderTests(
|
||||
val referenceState = generateStateRef()
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().plus(30.minutes))
|
||||
|
||||
val result = uniquenessProvider.commit(
|
||||
listOf(inputState), firstTxId, identity, requestSignature, timeWindow, references = listOf(referenceState))
|
||||
.get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(inputState), firstTxId, timeWindow, references = listOf(referenceState))
|
||||
|
||||
// Spend the reference state.
|
||||
val referenceSpend = uniquenessProvider.commit(
|
||||
listOf(referenceState),
|
||||
digestService.randomHash(),
|
||||
identity,
|
||||
requestSignature,
|
||||
timeWindow,
|
||||
emptyList()).get()
|
||||
assert(referenceSpend is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(referenceState), digestService.randomHash(), timeWindow)
|
||||
|
||||
// Idempotency: can re-notarise successfully
|
||||
testClock.advanceBy(90.minutes)
|
||||
val result2 = uniquenessProvider.commit(
|
||||
listOf(inputState), firstTxId, identity, requestSignature, timeWindow, references = listOf(referenceState))
|
||||
.get()
|
||||
val result = commit(listOf(inputState), firstTxId, timeWindow, references = listOf(referenceState)).get()
|
||||
// Known failure - this should return success. Will be fixed in a future release.
|
||||
assert(result2 is UniquenessProvider.Result.Failure)
|
||||
assertThat(result).isInstanceOf(Result.Failure::class.java)
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `rejects transaction with unused reference states and used input states`() {
|
||||
fun `rejects transaction with unused reference states and used input states`() {
|
||||
val firstTxId = digestService.randomHash()
|
||||
val inputState = generateStateRef()
|
||||
val referenceState = generateStateRef()
|
||||
|
||||
val result = uniquenessProvider.commit(listOf(inputState), firstTxId, identity, requestSignature, references = emptyList()).get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(inputState), firstTxId, references = emptyList())
|
||||
|
||||
// Transaction referencing the spent sate fails.
|
||||
val secondTxId = digestService.randomHash()
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().plus(30.minutes))
|
||||
val result2 = uniquenessProvider.commit(listOf(inputState), secondTxId, identity, requestSignature, timeWindow, references = listOf(referenceState))
|
||||
.get()
|
||||
val error = (result2 as UniquenessProvider.Result.Failure).error as NotaryError.Conflict
|
||||
val conflictCause = error.consumedStates[inputState]!!
|
||||
assertEquals(conflictCause.hashOfTransactionId, firstTxId.reHash())
|
||||
assertEquals(StateConsumptionDetails.ConsumedStateType.INPUT_STATE, conflictCause.type)
|
||||
val consumedStates = expectConflict(listOf(inputState), secondTxId, timeWindow, references = listOf(referenceState))
|
||||
assertThat(consumedStates[inputState]).isEqualTo(StateConsumptionDetails(firstTxId.reHash(), INPUT_STATE))
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `rejects transaction with used reference states and unused input states`() {
|
||||
fun `rejects transaction with used reference states and unused input states`() {
|
||||
val firstTxId = digestService.randomHash()
|
||||
val inputState = generateStateRef()
|
||||
val referenceState = generateStateRef()
|
||||
|
||||
val result = uniquenessProvider.commit(listOf(referenceState), firstTxId, identity, requestSignature, references = emptyList())
|
||||
.get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
expectCommitSuccess(listOf(referenceState), firstTxId, references = emptyList())
|
||||
|
||||
// Transaction referencing the spent sate fails.
|
||||
val secondTxId = digestService.randomHash()
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().plus(30.minutes))
|
||||
val result2 = uniquenessProvider.commit(listOf(inputState), secondTxId, identity, requestSignature, timeWindow, references = listOf(referenceState))
|
||||
.get()
|
||||
val error = (result2 as UniquenessProvider.Result.Failure).error as NotaryError.Conflict
|
||||
val conflictCause = error.consumedStates[referenceState]!!
|
||||
assertEquals(conflictCause.hashOfTransactionId, firstTxId.reHash())
|
||||
assertEquals(StateConsumptionDetails.ConsumedStateType.REFERENCE_INPUT_STATE, conflictCause.type)
|
||||
val consumedStates = expectConflict(listOf(inputState), secondTxId, timeWindow, references = listOf(referenceState))
|
||||
assertThat(consumedStates[referenceState]).isEqualTo(StateConsumptionDetails(firstTxId.reHash(), REFERENCE_INPUT_STATE))
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
@ -569,41 +455,93 @@ class UniquenessProviderTests(
|
||||
val referenceState = generateStateRef()
|
||||
|
||||
// Ensure batch contains duplicates
|
||||
val validFuture1 = uniquenessProvider.commit(
|
||||
emptyList(), secondTxId, identity, requestSignature, references = listOf(referenceState))
|
||||
val validFuture2 = uniquenessProvider.commit(
|
||||
emptyList(), secondTxId, identity, requestSignature, references = listOf(referenceState))
|
||||
val validFuture3 = uniquenessProvider.commit(
|
||||
listOf(referenceState), firstTxId, identity, requestSignature)
|
||||
val validFuture1 = commit(emptyList(), secondTxId, references = listOf(referenceState))
|
||||
val validFuture2 = commit(emptyList(), secondTxId, references = listOf(referenceState))
|
||||
val validFuture3 = commit(listOf(referenceState), firstTxId)
|
||||
|
||||
// Attempt to use the reference state after it has been consumed
|
||||
val validFuture4 = uniquenessProvider.commit(
|
||||
emptyList(), digestService.randomHash(), identity, requestSignature, references = listOf(referenceState))
|
||||
val validFuture4 = commit(emptyList(), digestService.randomHash(), references = listOf(referenceState))
|
||||
|
||||
// Ensure that transactions are processed correctly and duplicates get the same responses to original
|
||||
assert(validFuture1.get() is UniquenessProvider.Result.Success)
|
||||
assert(validFuture2.get() is UniquenessProvider.Result.Success)
|
||||
assert(validFuture3.get() is UniquenessProvider.Result.Success)
|
||||
assert(validFuture4.get() is UniquenessProvider.Result.Failure)
|
||||
assertThat(validFuture1.get()).isInstanceOf(Result.Success::class.java)
|
||||
assertThat(validFuture2.get()).isInstanceOf(Result.Success::class.java)
|
||||
assertThat(validFuture3.get()).isInstanceOf(Result.Success::class.java)
|
||||
assertThat(validFuture4.get()).isInstanceOf(Result.Failure::class.java)
|
||||
}
|
||||
|
||||
/* Group G: input, reference states and time window – covered by previous tests. */
|
||||
|
||||
/* Transaction signing tests. */
|
||||
@Test(timeout=300_000)
|
||||
fun `signs transactions correctly`() {
|
||||
fun `signs transactions correctly`() {
|
||||
(1..10).map {
|
||||
val inputState1 = generateStateRef()
|
||||
val firstTxId = digestService.randomHash()
|
||||
val timeWindow = TimeWindow.untilOnly(Clock.systemUTC().instant().plus(30.minutes))
|
||||
Pair(firstTxId, uniquenessProvider.commit(listOf(inputState1), firstTxId, identity, requestSignature, timeWindow))
|
||||
}.forEach {
|
||||
val result = it.second.get()
|
||||
assert(result is UniquenessProvider.Result.Success)
|
||||
val signature = (result as UniquenessProvider.Result.Success).signature
|
||||
assert(signature.verify(it.first))
|
||||
Pair(firstTxId, commit(listOf(inputState1), firstTxId, timeWindow))
|
||||
}.forEach { (txId, future) ->
|
||||
val result = future.get()
|
||||
assertThat(result).isInstanceOf(Result.Success::class.java)
|
||||
val signature = (result as Result.Success).signature
|
||||
signature.verify(txId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun commit(
|
||||
states: List<StateRef>,
|
||||
txId: SecureHash,
|
||||
timeWindow: TimeWindow? = null,
|
||||
references: List<StateRef> = emptyList()
|
||||
): CordaFuture<Result> {
|
||||
return uniquenessProvider.commit(states, txId, identity, requestSignature, timeWindow, references)
|
||||
}
|
||||
|
||||
private fun expectCommitSuccess(
|
||||
states: List<StateRef>,
|
||||
txId: SecureHash,
|
||||
timeWindow: TimeWindow? = null,
|
||||
references: List<StateRef> = emptyList()
|
||||
) {
|
||||
val result = commit(states, txId, timeWindow, references).get()
|
||||
assertThat(result).isInstanceOf(Result.Success::class.java)
|
||||
result as Result.Success
|
||||
result.signature.verify(txId)
|
||||
}
|
||||
|
||||
private fun expectCommitFailure(
|
||||
states: List<StateRef>,
|
||||
txId: SecureHash,
|
||||
timeWindow: TimeWindow? = null,
|
||||
references: List<StateRef> = emptyList()
|
||||
): NotaryError {
|
||||
val result = commit(states, txId, timeWindow, references).get()
|
||||
assertThat(result).isInstanceOf(Result.Failure::class.java)
|
||||
return (result as Result.Failure).error
|
||||
}
|
||||
|
||||
private fun expectInvalidTimeWindow(
|
||||
states: List<StateRef>,
|
||||
txId: SecureHash,
|
||||
timeWindow: TimeWindow,
|
||||
references: List<StateRef> = emptyList()
|
||||
) {
|
||||
val notaryError = expectCommitFailure(states, txId, timeWindow, references)
|
||||
assertThat(notaryError).isInstanceOf(NotaryError.TimeWindowInvalid::class.java)
|
||||
assertThat((notaryError as NotaryError.TimeWindowInvalid).txTimeWindow).isEqualTo(timeWindow)
|
||||
}
|
||||
|
||||
private fun expectConflict(
|
||||
states: List<StateRef>,
|
||||
txId: SecureHash,
|
||||
timeWindow: TimeWindow? = null,
|
||||
references: List<StateRef> = emptyList()
|
||||
): Map<StateRef, StateConsumptionDetails> {
|
||||
val notaryError = expectCommitFailure(states, txId, timeWindow, references)
|
||||
assertThat(notaryError).isInstanceOf(NotaryError.Conflict::class.java)
|
||||
val conflict = notaryError as NotaryError.Conflict
|
||||
assertThat(conflict.txId).isEqualTo(txId)
|
||||
return conflict.consumedStates
|
||||
}
|
||||
}
|
||||
|
||||
interface UniquenessProviderFactory {
|
||||
@ -644,7 +582,7 @@ class RaftUniquenessProviderFactory : UniquenessProviderFactory {
|
||||
}
|
||||
|
||||
|
||||
class JPAUniquenessProviderFactory(val digestService: DigestService) : UniquenessProviderFactory {
|
||||
class JPAUniquenessProviderFactory(private val digestService: DigestService) : UniquenessProviderFactory {
|
||||
private var database: CordaPersistence? = null
|
||||
private val notaryConfig = JPANotaryConfiguration(maxInputStates = 10)
|
||||
private val notaryWorkerName = CordaX500Name.parse("CN=NotaryWorker, O=Corda, L=London, C=GB")
|
||||
|
@ -25,6 +25,7 @@ dependencies {
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"
|
||||
testImplementation "org.mockito:mockito-core:$mockito_version"
|
||||
testImplementation "org.assertj:assertj-core:$assertj_version"
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
@ -10,6 +10,7 @@ import net.corda.nodeapi.internal.network.PackageOwner
|
||||
import net.corda.testing.core.ALICE_NAME
|
||||
import net.corda.testing.core.internal.JarSignatureTestUtils.generateKey
|
||||
import net.corda.testing.core.internal.JarSignatureTestUtils.getPublicKey
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.AfterClass
|
||||
import org.junit.Before
|
||||
@ -251,7 +252,7 @@ class NetworkBootstrapperRunnerTests {
|
||||
runner.networkParametersFile = conf
|
||||
val exitCode = runner.runProgram()
|
||||
val output = errContent.toString()
|
||||
assert(output.contains("Error parsing packageOwnership: Package namespaces must not overlap"))
|
||||
assertThat(output).contains("Error parsing packageOwnership: Package namespaces must not overlap")
|
||||
assertEquals(1, exitCode)
|
||||
}
|
||||
|
||||
@ -260,6 +261,6 @@ class NetworkBootstrapperRunnerTests {
|
||||
val (runner, _) = getRunner()
|
||||
runner.networkParametersFile = dirAlice / "filename-that-doesnt-exist"
|
||||
val exception = assertFailsWith<FileNotFoundException> { runner.runProgram() }
|
||||
assert(exception.message!!.startsWith("Unable to find specified network parameters config file at"))
|
||||
assertThat(exception.message).startsWith("Unable to find specified network parameters config file at")
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user