mirror of
https://github.com/corda/corda.git
synced 2025-06-23 17:53:31 +00:00
CORDA-941 - Add Network Parameters contract implementation Whitelist (#2539)
* CORDA-941 Add Network Parameters contract implementation Whitelist * CORDA-941 fix merge * CORDA-941 added uploader support to Attachments and added check into the AttachmentClassloader to only allow loading attachments that were uploaded from the local cordapps folder * CORDA-941 update api spec * CORDA-941 address some code review changes and fix and add classloader test * CORDA-941 fix test * CORDA-941 address code review comments * CORDA-941 address code review comments - use and update existing whitelist * CORDA-941 address code review comments * CORDA-941 fix compile error * CORDA-941 address code review comments * CORDA-941 removed: whitelistAllContractsForTest * CORDA-941 removed: whitelistAllContractsForTest * CORDA-941 add comment * CORDA-941 remove toLedgerTransaction * CORDA-941 add warning when node not using latest CorDapp * CORDA-941 remove the stubbing approach for cleaning LedgerTransaction * CORDA-941 Code review changes * CORDA-941 Fix merge * CORDA-941 workaround for api scanner bug * Fixed JacksonSupportTest.
This commit is contained in:
committed by
Katelyn Baker
parent
34e82026f3
commit
60a4bcba5b
@ -226,7 +226,7 @@ open class MockServices private constructor(
|
||||
return NodeInfo(listOf(NetworkHostAndPort("mock.node.services", 10000)), listOf(initialIdentity.identity), 1, serial = 1L)
|
||||
}
|
||||
override val transactionVerifierService: TransactionVerifierService get() = InMemoryTransactionVerifierService(2)
|
||||
private val mockCordappProvider: MockCordappProvider = MockCordappProvider(cordappLoader, attachments)
|
||||
private val mockCordappProvider: MockCordappProvider = MockCordappProvider(cordappLoader, attachments, networkParameters.whitelistedContractImplementations)
|
||||
override val cordappProvider: CordappProvider get() = mockCordappProvider
|
||||
|
||||
internal fun makeVaultService(hibernateConfig: HibernateConfiguration, schemaService: SchemaService): VaultServiceInternal {
|
||||
|
@ -39,7 +39,7 @@ class NetworkMapServer(private val cacheTimeout: Duration,
|
||||
private val myHostNameValue: String = "test.host.name",
|
||||
vararg additionalServices: Any) : Closeable {
|
||||
companion object {
|
||||
private val stubNetworkParameters = NetworkParameters(1, emptyList(), 10485760, Int.MAX_VALUE, Instant.now(), 10)
|
||||
private val stubNetworkParameters = NetworkParameters(1, emptyList(), 10485760, Int.MAX_VALUE, Instant.now(), 10, emptyMap())
|
||||
}
|
||||
|
||||
private val server: Server
|
||||
|
@ -19,6 +19,7 @@ fun testNetworkParameters(
|
||||
modifiedTime = modifiedTime,
|
||||
maxMessageSize = maxMessageSize,
|
||||
maxTransactionSize = maxTransactionSize,
|
||||
epoch = epoch
|
||||
epoch = epoch,
|
||||
whitelistedContractImplementations = emptyMap()
|
||||
)
|
||||
}
|
@ -2,6 +2,7 @@ package net.corda.testing.internal
|
||||
|
||||
import net.corda.core.contracts.ContractClassName
|
||||
import net.corda.core.cordapp.Cordapp
|
||||
import net.corda.core.internal.TEST_UPLOADER
|
||||
import net.corda.core.internal.cordapp.CordappImpl
|
||||
import net.corda.core.node.services.AttachmentId
|
||||
import net.corda.core.node.services.AttachmentStorage
|
||||
@ -11,7 +12,9 @@ import net.corda.testing.services.MockAttachmentStorage
|
||||
import java.nio.file.Paths
|
||||
import java.util.*
|
||||
|
||||
class MockCordappProvider(cordappLoader: CordappLoader, attachmentStorage: AttachmentStorage) : CordappProviderImpl(cordappLoader, attachmentStorage) {
|
||||
class MockCordappProvider(cordappLoader: CordappLoader,
|
||||
attachmentStorage: AttachmentStorage,
|
||||
whitelistedContractImplementations: Map<String, List<AttachmentId>>) : CordappProviderImpl(cordappLoader, attachmentStorage, whitelistedContractImplementations) {
|
||||
val cordappRegistry = mutableListOf<Pair<Cordapp, AttachmentId>>()
|
||||
|
||||
fun addMockCordapp(contractClassName: ContractClassName, attachments: MockAttachmentStorage) {
|
||||
@ -27,20 +30,21 @@ class MockCordappProvider(cordappLoader: CordappLoader, attachmentStorage: Attac
|
||||
customSchemas = emptySet(),
|
||||
jarPath = Paths.get("").toUri().toURL())
|
||||
if (cordappRegistry.none { it.first.contractClassNames.contains(contractClassName) }) {
|
||||
cordappRegistry.add(Pair(cordapp, findOrImportAttachment(contractClassName.toByteArray(), attachments)))
|
||||
cordappRegistry.add(Pair(cordapp, findOrImportAttachment(listOf(contractClassName), contractClassName.toByteArray(), attachments)))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getContractAttachmentID(contractClassName: ContractClassName): AttachmentId? = cordappRegistry.find { it.first.contractClassNames.contains(contractClassName) }?.second ?: super.getContractAttachmentID(contractClassName)
|
||||
override fun getContractAttachmentID(contractClassName: ContractClassName): AttachmentId? = cordappRegistry.find { it.first.contractClassNames.contains(contractClassName) }?.second
|
||||
?: super.getContractAttachmentID(contractClassName)
|
||||
|
||||
private fun findOrImportAttachment(data: ByteArray, attachments: MockAttachmentStorage): AttachmentId {
|
||||
private fun findOrImportAttachment(contractClassNames: List<ContractClassName>, data: ByteArray, attachments: MockAttachmentStorage): AttachmentId {
|
||||
val existingAttachment = attachments.files.filter {
|
||||
Arrays.equals(it.value, data)
|
||||
Arrays.equals(it.value.second, data)
|
||||
}
|
||||
return if (!existingAttachment.isEmpty()) {
|
||||
existingAttachment.keys.first()
|
||||
} else {
|
||||
attachments.importAttachment(data.inputStream())
|
||||
attachments.importContractAttachment(contractClassNames, TEST_UPLOADER, data.inputStream())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
package net.corda.testing.services
|
||||
|
||||
import net.corda.core.contracts.Attachment
|
||||
import net.corda.core.contracts.ContractAttachment
|
||||
import net.corda.core.contracts.ContractClassName
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.sha256
|
||||
import net.corda.core.internal.AbstractAttachment
|
||||
import net.corda.core.internal.UNKNOWN_UPLOADER
|
||||
import net.corda.core.node.services.AttachmentId
|
||||
import net.corda.core.node.services.AttachmentStorage
|
||||
import net.corda.core.node.services.vault.AttachmentQueryCriteria
|
||||
import net.corda.core.node.services.vault.AttachmentSort
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
import net.corda.nodeapi.internal.withContractsInJar
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.InputStream
|
||||
import java.util.*
|
||||
@ -24,31 +28,17 @@ class MockAttachmentStorage : AttachmentStorage, SingletonSerializeAsToken() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun importAttachment(jar: InputStream): AttachmentId {
|
||||
// JIS makes read()/readBytes() return bytes of the current file, but we want to hash the entire container here.
|
||||
require(jar !is JarInputStream)
|
||||
val files = HashMap<SecureHash, Pair<Attachment, ByteArray>>()
|
||||
|
||||
val bytes = getBytes(jar)
|
||||
override fun importAttachment(jar: InputStream): AttachmentId = importAttachment(jar, UNKNOWN_UPLOADER, null)
|
||||
|
||||
val sha256 = bytes.sha256()
|
||||
if (!files.containsKey(sha256)) {
|
||||
files[sha256] = bytes
|
||||
override fun importAttachment(jar: InputStream, uploader: String, filename: String?): AttachmentId {
|
||||
return withContractsInJar(jar) { contractClassNames, inputStream ->
|
||||
importAttachmentInternal(inputStream, uploader, filename, contractClassNames)
|
||||
}
|
||||
return sha256
|
||||
}
|
||||
|
||||
override fun importAttachment(jar: InputStream, uploader: String, filename: String): AttachmentId {
|
||||
return importAttachment(jar)
|
||||
}
|
||||
|
||||
val files = HashMap<SecureHash, ByteArray>()
|
||||
|
||||
private class MockAttachment(dataLoader: () -> ByteArray, override val id: SecureHash): AbstractAttachment(dataLoader)
|
||||
|
||||
override fun openAttachment(id: SecureHash): Attachment? {
|
||||
val f = files[id] ?: return null
|
||||
return MockAttachment({f}, id)
|
||||
}
|
||||
override fun openAttachment(id: SecureHash): Attachment? = files[id]?.first
|
||||
|
||||
override fun queryAttachments(criteria: AttachmentQueryCriteria, sorting: AttachmentSort?): List<AttachmentId> {
|
||||
throw NotImplementedError("Querying for attachments not implemented")
|
||||
@ -56,18 +46,33 @@ class MockAttachmentStorage : AttachmentStorage, SingletonSerializeAsToken() {
|
||||
|
||||
override fun hasAttachment(attachmentId: AttachmentId) = files.containsKey(attachmentId)
|
||||
|
||||
fun getAttachmentIdAndBytes(jar: InputStream): Pair<AttachmentId, ByteArray> {
|
||||
val bytes = getBytes(jar)
|
||||
return Pair(bytes.sha256(), bytes)
|
||||
}
|
||||
|
||||
override fun importOrGetAttachment(jar: InputStream): AttachmentId {
|
||||
try {
|
||||
return importAttachment(jar)
|
||||
}
|
||||
catch (faee: java.nio.file.FileAlreadyExistsException) {
|
||||
} catch (faee: java.nio.file.FileAlreadyExistsException) {
|
||||
return AttachmentId.parse(faee.message!!)
|
||||
}
|
||||
}
|
||||
|
||||
fun importContractAttachment(contractClassNames: List<ContractClassName>, uploader: String, jar: InputStream): AttachmentId = importAttachmentInternal(jar, uploader, null, contractClassNames)
|
||||
|
||||
fun getAttachmentIdAndBytes(jar: InputStream): Pair<AttachmentId, ByteArray> = getBytes(jar).let { bytes -> Pair(bytes.sha256(), bytes) }
|
||||
|
||||
private class MockAttachment(dataLoader: () -> ByteArray, override val id: SecureHash): AbstractAttachment(dataLoader)
|
||||
|
||||
private fun importAttachmentInternal(jar: InputStream, uploader: String, filename: String?, contractClassNames: List<ContractClassName>? = null): AttachmentId {
|
||||
// JIS makes read()/readBytes() return bytes of the current file, but we want to hash the entire container here.
|
||||
require(jar !is JarInputStream)
|
||||
|
||||
val bytes = getBytes(jar)
|
||||
|
||||
val sha256 = bytes.sha256()
|
||||
if (sha256 !in files.keys) {
|
||||
val baseAttachment = MockAttachment({ bytes }, sha256)
|
||||
val attachment = if (contractClassNames == null || contractClassNames.isEmpty()) baseAttachment else ContractAttachment(baseAttachment, contractClassNames.first(), contractClassNames.toSet(), uploader)
|
||||
files[sha256] = Pair(attachment, bytes)
|
||||
}
|
||||
return sha256
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user