Add unit tests around vault update derivation

This commit is contained in:
Ross Nicoll 2017-07-11 14:21:37 +01:00
parent 7eed258bcb
commit f6aa672215
2 changed files with 64 additions and 11 deletions

View File

@ -2,6 +2,7 @@ package net.corda.node.services.vault
import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.strands.Strand
import com.google.common.annotations.VisibleForTesting
import io.requery.PersistenceException
import io.requery.TransactionIsolation
import io.requery.kotlin.`in`
@ -468,7 +469,8 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
private fun deriveState(txState: TransactionState<Cash.State>, amount: Amount<Issued<Currency>>, owner: AbstractParty)
= txState.copy(data = txState.data.copy(amount = amount, owner = owner))
private fun makeUpdate(tx: WireTransaction, ourKeys: Set<PublicKey>): Vault.Update {
@VisibleForTesting
internal fun makeUpdate(tx: WireTransaction, ourKeys: Set<PublicKey>): Vault.Update {
val ourNewStates = tx.outputs.
filter { isRelevant(it.data, ourKeys) }.
map { tx.outRef<ContractState>(it.data) }
@ -515,7 +517,8 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
authorisedUpgrade.remove(stateAndRef.ref)
}
private fun isRelevant(state: ContractState, ourKeys: Set<PublicKey>) = when (state) {
@VisibleForTesting
internal fun isRelevant(state: ContractState, ourKeys: Set<PublicKey>) = when (state) {
is OwnableState -> state.owner.owningKey.containsAny(ourKeys)
is LinearState -> state.isRelevant(ourKeys)
else -> ourKeys.intersect(state.participants.map { it.owningKey }).isNotEmpty()

View File

@ -2,22 +2,20 @@ package net.corda.node.services.vault
import net.corda.contracts.asset.Cash
import net.corda.contracts.asset.DUMMY_CASH_ISSUER
import net.corda.testing.contracts.fillWithSomeTestCash
import net.corda.core.contracts.*
import net.corda.core.crypto.generateKeyPair
import net.corda.core.identity.AnonymousParty
import net.corda.core.node.services.StatesNotAvailableException
import net.corda.core.node.services.Vault
import net.corda.core.node.services.VaultService
import net.corda.core.node.services.unconsumedStates
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.transactions.SignedTransaction
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.LogHelper
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.OpaqueBytes
import net.corda.node.utilities.configureDatabase
import net.corda.node.utilities.transaction
import net.corda.testing.BOC
import net.corda.testing.BOC_KEY
import net.corda.testing.MEGA_CORP
import net.corda.testing.MEGA_CORP_KEY
import net.corda.testing.*
import net.corda.testing.contracts.fillWithSomeTestCash
import net.corda.testing.node.MockServices
import net.corda.testing.node.makeTestDataSourceProperties
import org.assertj.core.api.Assertions.assertThat
@ -31,7 +29,9 @@ import java.util.*
import java.util.concurrent.CountDownLatch
import java.util.concurrent.Executors
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNull
import kotlin.test.assertTrue
class NodeVaultServiceTest {
lateinit var services: MockServices
@ -420,8 +420,58 @@ class NodeVaultServiceTest {
services.recordTransactions(anotherTX)
vaultSvc.addNoteToTransaction(anotherTX.id, "GPB Sample Note 1")
vaultSvc.addNoteToTransaction(anotherTX.id, "GBP Sample Note 1")
assertEquals(1, vaultSvc.getTransactionNotes(anotherTX.id).count())
}
}
@Test
fun `is ownable state relevant`() {
val service = (services.vaultService as NodeVaultService)
val amount = Amount(1000, Issued(BOC.ref(1), GBP))
val wellKnownCash = Cash.State(amount, services.myInfo.legalIdentity)
assertTrue { service.isRelevant(wellKnownCash, services.keyManagementService.keys) }
val anonymousIdentity = services.keyManagementService.freshKeyAndCert(services.myInfo.legalIdentityAndCert, false)
val anonymousCash = Cash.State(amount, anonymousIdentity.identity)
assertTrue { service.isRelevant(anonymousCash, services.keyManagementService.keys) }
val thirdPartyIdentity = AnonymousParty(generateKeyPair().public)
val thirdPartyCash = Cash.State(amount, thirdPartyIdentity)
assertFalse { service.isRelevant(thirdPartyCash, services.keyManagementService.keys) }
}
// TODO: Unit test linear state relevancy checks
@Test
fun `make update`() {
val service = (services.vaultService as NodeVaultService)
val anonymousIdentity = services.keyManagementService.freshKeyAndCert(services.myInfo.legalIdentityAndCert, false)
val thirdPartyIdentity = AnonymousParty(generateKeyPair().public)
val amount = Amount(1000, Issued(BOC.ref(1), GBP))
// Issue then move some cash
val issueTx = TransactionBuilder(TransactionType.General, services.myInfo.legalIdentity).apply {
Cash().generateIssue(this,
amount, anonymousIdentity.identity, services.myInfo.legalIdentity)
}.toWireTransaction()
val cashState = StateAndRef(issueTx.outputs.single(), StateRef(issueTx.id, 0))
database.transaction {
val expected = Vault.Update(emptySet(), setOf(cashState), null)
val actual = service.makeUpdate(issueTx, setOf(anonymousIdentity.identity.owningKey))
assertEquals(expected, actual)
services.vaultService.notify(issueTx)
}
database.transaction {
val moveTx = TransactionBuilder(TransactionType.General, services.myInfo.legalIdentity).apply {
services.vaultService.generateSpend(this, Amount(1000, GBP), thirdPartyIdentity)
}.toWireTransaction()
val expected = Vault.Update(setOf(cashState), emptySet(), null)
val actual = service.makeUpdate(moveTx, setOf(anonymousIdentity.identity.owningKey))
assertEquals(expected, actual)
}
}
}