mirror of
https://github.com/corda/corda.git
synced 2025-03-15 00:36:49 +00:00
Merge fixes
Fix bug Fix bug Fix tests Fix tests
This commit is contained in:
parent
3233d1d91f
commit
8dc394b117
@ -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 }
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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))
|
||||
)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user