Merge fixes

Fix bug

Fix bug

Fix tests

Fix tests
This commit is contained in:
Tudor Malene 2018-10-23 11:24:24 +01:00 committed by tudor.malene@gmail.com
parent 3233d1d91f
commit 8dc394b117
11 changed files with 26 additions and 80 deletions

View File

@ -67,9 +67,9 @@ object JarSignatureCollector {
(it.signerCertPath.certificates[0] as X509Certificate).publicKey
}.sortedBy { it.hash} // Sorted for determinism.
private fun Set<CodeSigner>.toOrderedPublicKeys(): List<PublicKey> = map {
(it.signerCertPath.certificates[0] as X509Certificate).publicKey
}.sortedBy { it.hash} // Sorted for determinism.
private fun Set<CodeSigner>.toPartiesOrderedByName(): List<Party> = map {
Party(it.signerCertPath.certificates[0] as X509Certificate)
}.sortedBy { it.name.toString() } // Sorted for determinism.
private val JarInputStream.entries get(): Sequence<JarEntry> = generateSequence(nextJarEntry) { nextJarEntry }
}

View File

@ -107,30 +107,6 @@ data class LedgerTransaction @JvmOverloads constructor(
}
}
/**
* Verify that package ownership is respected.
*
* TODO - revisit once transaction contains network parameters.
*/
private fun validatePackageOwnership(contractAttachmentsByContract: Map<ContractClassName, ContractAttachment>) {
// This should never happen once we have network parameters in the transaction.
if (networkParameters == null) {
return
}
val contractsAndOwners = allStates.mapNotNull { transactionState ->
val contractClassName = transactionState.contract
networkParameters.getOwnerOf(contractClassName)?.let { contractClassName to it }
}.toMap()
contractsAndOwners.forEach { contract, owner ->
val attachment = contractAttachmentsByContract[contract]!!
if (!owner.isFulfilledBy(attachment.signers)) {
throw TransactionVerificationException.ContractAttachmentNotSignedByPackageOwnerException(this.id, id, contract)
}
}
}
/**
* Verify that for each contract the network wide package owner is respected.
*

View File

@ -181,7 +181,7 @@ open class TransactionBuilder @JvmOverloads constructor(
val resolvedStates: List<TransactionState<ContractState>> = contractAttachmentsAndResolvedOutputStates.mapNotNull { it.second }.flatten()
// The output states need to preserve the order in which they were added.
val resolvedOutputStatesInTheOriginalOrder: List<TransactionState<ContractState>> = outputStates().map { os -> resolvedStates.find { rs -> rs.data == os.data }!! }
val resolvedOutputStatesInTheOriginalOrder: List<TransactionState<ContractState>> = outputStates().map { os -> resolvedStates.find { rs -> rs.data == os.data && rs.encumbrance == os.encumbrance}!! }
val attachments: Collection<AttachmentId> = contractAttachmentsAndResolvedOutputStates.map { it.first } + refStateContractAttachments

View File

@ -25,8 +25,8 @@ object JarSignatureTestUtils {
.waitFor())
}
fun Path.generateKey(alias: String, password: String, name: String) =
executeProcess("keytool", "-genkey", "-keystore", "_teststore", "-storepass", "storepass", "-keyalg", "RSA", "-alias", alias, "-keypass", password, "-dname", name)
fun Path.generateKey(alias: String, password: String, name: String, keyalg: String = "RSA") =
executeProcess("keytool", "-genkey", "-keystore", "_teststore", "-storepass", "storepass", "-keyalg", keyalg, "-alias", alias, "-keypass", password, "-dname", name)
fun Path.createJar(fileName: String, vararg contents: String) =
executeProcess(*(arrayOf("jar", "cvf", fileName) + contents))

View File

@ -34,9 +34,9 @@ class JarSignatureCollectorTest {
@BeforeClass
@JvmStatic
fun beforeClass() {
dir.generateKey(ALICE, ALICE_PASS, ALICE_NAME)
dir.generateKey(BOB, BOB_PASS, BOB_NAME)
dir.generateKey(CHARLIE, CHARLIE_PASS, CHARLIE_NAME, "EC")
dir.generateKey(ALICE, ALICE_PASS, ALICE_NAME.toString())
dir.generateKey(BOB, BOB_PASS, BOB_NAME.toString())
dir.generateKey(CHARLIE, CHARLIE_PASS, CHARLIE_NAME.toString(), "EC")
(dir / "_signable1").writeLines(listOf("signable1"))
(dir / "_signable2").writeLines(listOf("signable2"))
@ -134,13 +134,13 @@ class JarSignatureCollectorTest {
// Signing using EC algorithm produced JAR File spec incompatible signature block (META-INF/*.EC) which is anyway accepted by jarsiner, see [JarSignatureCollector]
@Test
fun `one signer with EC sign algorithm`() {
createJar("_signable1", "_signable2")
signJar(CHARLIE, CHARLIE_PASS)
assertEquals(listOf(CHARLIE_NAME), getJarSigners().names) // We only reused CHARLIE's distinguished name, so the keys will be different.
dir.createJar(FILENAME, "_signable1", "_signable2")
val charlieKey = dir.signJar(FILENAME, CHARLIE, CHARLIE_PASS)
assertEquals(setOf(charlieKey), dir.getJarSigners(FILENAME).toSet()) // We only reused CHARLIE's distinguished name, so the keys will be different.
(dir / "my-dir").createDirectory()
updateJar("my-dir")
assertEquals(listOf(CHARLIE_NAME), getJarSigners().names) // Unsigned directory is irrelevant.
dir.updateJar(FILENAME, "my-dir")
assertEquals(setOf(charlieKey), dir.getJarSigners(FILENAME).toSet()) // Unsigned directory is irrelevant.
}
private fun signAsAlice() = dir.signJar(FILENAME, ALICE, ALICE_PASS)

View File

@ -481,7 +481,7 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
vaultFiller.fillWithSomeTestLinearStates(1, constraint = AlwaysAcceptAttachmentConstraint).states.first().state.constraint
vaultFiller.fillWithSomeTestLinearStates(1, constraint = WhitelistedByZoneAttachmentConstraint).states.first().state.constraint
// hash constraint
val linearStateHash = vaultFiller.fillWithSomeTestLinearStates(1, constraint = HashAttachmentConstraint(SecureHash.randomSHA256()))
val linearStateHash = vaultFiller.fillWithSomeTestLinearStates(1, constraint = AutomaticPlaceholderConstraint) // defaults to the HashConstraint
val constraintHash = linearStateHash.states.first().state.constraint as HashAttachmentConstraint
// signature constraint (single key)
val linearStateSignature = vaultFiller.fillWithSomeTestLinearStates(1, constraint = SignatureAttachmentConstraint(alice.publicKey))
@ -504,7 +504,7 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
val constraintTypeCriteria2 = VaultQueryCriteria(constraintTypes = setOf(HASH))
val constraintResults2 = vaultService.queryBy<LinearState>(constraintTypeCriteria2)
assertThat(constraintResults2.states).hasSize(2)
assertThat(constraintResults2.states.map { it.state.constraint }).containsOnlyOnce(constraintHash)
assertThat(constraintResults2.states.map { it.state.constraint }.toSet()).isEqualTo(setOf(constraintHash))
// search for states with [Vault.ConstraintInfo.Type] either HASH or CZ_WHITELISED
// DOCSTART VaultQueryExample30
@ -536,7 +536,7 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
val alwaysAcceptConstraint = vaultFiller.fillWithSomeTestLinearStates(1, constraint = AlwaysAcceptAttachmentConstraint).states.first().state.constraint
vaultFiller.fillWithSomeTestLinearStates(1, constraint = WhitelistedByZoneAttachmentConstraint)
// hash constraint
val linearStateHash = vaultFiller.fillWithSomeTestLinearStates(1, constraint = HashAttachmentConstraint(SecureHash.randomSHA256()))
val linearStateHash = vaultFiller.fillWithSomeTestLinearStates(1, constraint = AutomaticPlaceholderConstraint) // defaults to the hash constraint.
val constraintHash = linearStateHash.states.first().state.constraint as HashAttachmentConstraint
// signature constraint (single key)
val linearStateSignature = vaultFiller.fillWithSomeTestLinearStates(1, constraint = SignatureAttachmentConstraint(alice.publicKey))
@ -559,7 +559,7 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
// search for states for a specific HashAttachmentConstraint
val constraintsCriteria2 = VaultQueryCriteria(constraints = setOf(Vault.ConstraintInfo(constraintHash)))
val constraintResults2 = vaultService.queryBy<LinearState>(constraintsCriteria2)
assertThat(constraintResults2.states).hasSize(1)
assertThat(constraintResults2.states).hasSize(2)
assertThat(constraintResults2.states.first().state.constraint).isEqualTo(constraintHash)
// search for states with a specific SignatureAttachmentConstraint constraint
@ -574,7 +574,7 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
Vault.ConstraintInfo(constraintSignatureCompositeKey), Vault.ConstraintInfo(constraintHash)))
val constraintResults = vaultService.queryBy<LinearState>(constraintCriteria)
// DOCEND VaultQueryExample31
assertThat(constraintResults.states).hasSize(3)
assertThat(constraintResults.states).hasSize(4)
assertThat(constraintResults.states.map { it.state.constraint }).containsAll(listOf(constraintHash, constraintSignature, constraintSignatureCompositeKey))
// exercise enriched query
@ -2337,7 +2337,7 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
database.transaction {
vaultFiller.fillWithSomeTestLinearStates(1, constraint = WhitelistedByZoneAttachmentConstraint)
vaultFiller.fillWithSomeTestLinearStates(1, constraint = SignatureAttachmentConstraint(alice.publicKey))
vaultFiller.fillWithSomeTestLinearStates(1, constraint = HashAttachmentConstraint( SecureHash.randomSHA256()))
vaultFiller.fillWithSomeTestLinearStates(1, constraint = AutomaticPlaceholderConstraint) // this defaults to the HashConstraint
vaultFiller.fillWithSomeTestLinearStates(1, constraint = AlwaysAcceptAttachmentConstraint)
// Base criteria

View File

@ -241,7 +241,7 @@ class MySQLNotaryServiceTests : IntegrationTest() {
val builder = DummyContract.generateInitial(Random().nextInt(), notary, node.info.singleIdentity().ref(0))
val stx = node.services.signInitialTransaction(builder)
node.services.recordTransactions(stx)
StateAndRef(builder.outputStates().first(), StateRef(stx.id, 0))
StateAndRef(stx.coreTransaction.outputs.first(), StateRef(stx.id, 0))
}
}

View File

@ -116,7 +116,7 @@ class CommercialPaperTestsGeneric {
// Some CP is issued onto the ledger by MegaCorp.
transaction("Issuance") {
attachments(CP_PROGRAM_ID, CommercialPaper.CP_PROGRAM_ID)
attachments(CP_PROGRAM_ID)
output(thisTest.getContract(), "paper", thisTest.getPaper())
command(MEGA_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
timeWindow(TEST_TX_TIME)
@ -126,7 +126,7 @@ class CommercialPaperTestsGeneric {
// The CP is sold to alice for her $900, $100 less than the face value. At 10% interest after only 7 days,
// that sounds a bit too good to be true!
transaction("Trade") {
attachments(Cash.PROGRAM_ID, CommercialPaper.CP_PROGRAM_ID)
attachments(Cash.PROGRAM_ID)
input("paper")
input("alice's $900")
output(Cash.PROGRAM_ID, "borrowed $900", 900.DOLLARS.CASH issuedBy issuer ownedBy MEGA_CORP)
@ -139,7 +139,7 @@ class CommercialPaperTestsGeneric {
// Time passes, and Alice redeem's her CP for $1000, netting a $100 profit. MegaCorp has received $1200
// as a single payment from somewhere and uses it to pay Alice off, keeping the remaining $200 as change.
transaction("Redemption") {
attachments(CP_PROGRAM_ID, CommercialPaper.CP_PROGRAM_ID)
attachments(CP_PROGRAM_ID)
input("alice's paper")
input("some profits")
@ -182,7 +182,6 @@ class CommercialPaperTestsGeneric {
@Test
fun `key mismatch at issue`() {
transaction {
attachment(CP_PROGRAM_ID)
attachment(CP_PROGRAM_ID)
output(thisTest.getContract(), thisTest.getPaper())
command(MINI_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
@ -194,7 +193,6 @@ class CommercialPaperTestsGeneric {
@Test
fun `face value is not zero`() {
transaction {
attachment(CP_PROGRAM_ID)
attachment(CP_PROGRAM_ID)
output(thisTest.getContract(), thisTest.getPaper().withFaceValue(0.DOLLARS `issued by` issuer))
command(MEGA_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
@ -206,7 +204,6 @@ class CommercialPaperTestsGeneric {
@Test
fun `maturity date not in the past`() {
transaction {
attachment(CP_PROGRAM_ID)
attachment(CP_PROGRAM_ID)
output(thisTest.getContract(), thisTest.getPaper().withMaturityDate(TEST_TX_TIME - 10.days))
command(MEGA_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
@ -218,7 +215,6 @@ class CommercialPaperTestsGeneric {
@Test
fun `issue cannot replace an existing state`() {
transaction {
attachment(CP_PROGRAM_ID)
attachment(CP_PROGRAM_ID)
input(thisTest.getContract(), thisTest.getPaper())
output(thisTest.getContract(), thisTest.getPaper())

View File

@ -567,7 +567,7 @@ class CashTests {
private fun makeCash(amount: Amount<Currency>, issuer: AbstractParty, depositRef: Byte = 1) =
StateAndRef(
TransactionState(Cash.State(amount `issued by` issuer.ref(depositRef), ourIdentity), Cash.PROGRAM_ID, DUMMY_NOTARY),
TransactionState(Cash.State(amount `issued by` issuer.ref(depositRef), ourIdentity), Cash.PROGRAM_ID, DUMMY_NOTARY, constraint = AlwaysAcceptAttachmentConstraint),
StateRef(SecureHash.randomSHA256(), Random().nextInt(32))
)

View File

@ -1,32 +1,6 @@
package net.corda.testing.dsl
import net.corda.core.DoNotImplement
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint
import net.corda.core.contracts.Attachment
import net.corda.core.contracts.AttachmentConstraint
import net.corda.core.contracts.AutomaticHashConstraint
import net.corda.core.contracts.CommandData
import net.corda.core.contracts.ContractClassName
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TimeWindow
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint
import net.corda.core.contracts.Attachment
import net.corda.core.contracts.AttachmentConstraint
import net.corda.core.contracts.AutomaticPlaceholderConstraint
import net.corda.core.contracts.CommandData
import net.corda.core.contracts.ContractClassName
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TimeWindow
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint
import net.corda.core.contracts.Attachment
import net.corda.core.contracts.AttachmentConstraint
import net.corda.core.contracts.CommandData
import net.corda.core.contracts.ContractClassName
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TimeWindow
import net.corda.core.contracts.*
import net.corda.core.crypto.SecureHash
import net.corda.core.identity.Party

View File

@ -103,7 +103,7 @@ class VaultFiller @JvmOverloads constructor(
linearNumber: Long = 0L,
linearBoolean: Boolean = false,
linearTimestamp: Instant = now(),
constraint: AttachmentConstraint = AutomaticHashConstraint): Vault<LinearState> {
constraint: AttachmentConstraint = AutomaticPlaceholderConstraint): Vault<LinearState> {
val myKey: PublicKey = services.myInfo.chooseIdentity().owningKey
val me = AnonymousParty(myKey)
val issuerKey = defaultNotary.keyPair