CORDA-4123 Change MockNetworkParameterStorage to not rehash NetworkParameters (#6872)

* CORDA-4123 Change Mock Network Parameter Storage to not rehash the Network Parameters

* Fix Detekt
This commit is contained in:
William Vigor 2021-02-16 16:25:38 +00:00 committed by GitHub
parent 1a7401472f
commit 7261442c98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 102 additions and 40 deletions

View File

@ -29,6 +29,7 @@ import net.corda.core.identity.Party
import net.corda.core.internal.concurrent.transpose
import net.corda.core.internal.copyBytes
import net.corda.core.messaging.startFlow
import net.corda.core.node.ServiceHub
import net.corda.core.serialization.CustomSerializationScheme
import net.corda.core.serialization.SerializationSchemeContext
import net.corda.core.serialization.internal.CustomSerializationSchemeUtils.Companion.getSchemeIdIfCustomSerializationMagic
@ -55,12 +56,28 @@ import org.objenesis.strategy.InstantiatorStrategy
import org.objenesis.strategy.StdInstantiatorStrategy
import java.io.ByteArrayOutputStream
import java.lang.reflect.Modifier
import java.security.PublicKey
import java.util.*
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class CustomSerializationSchemeDriverTest {
companion object {
private fun createWireTx(serviceHub: ServiceHub, notary: Party, key: PublicKey, schemeId: Int): WireTransaction {
val outputState = TransactionState(
data = DummyContract.DummyState(),
contract = DummyContract::class.java.name,
notary = notary,
constraint = AlwaysAcceptAttachmentConstraint
)
val builder = TransactionBuilder()
.addOutputState(outputState)
.addCommand(DummyCommandData, key)
return builder.toWireTransaction(serviceHub, schemeId)
}
}
@Test(timeout = 300_000)
fun `flow can send wire transaction serialized with custom kryo serializer`() {
driver(DriverParameters(notarySpecs = emptyList(), startNodesInProcess = true, cordappsForAllNodes = listOf(enclosedCordapp()))) {
@ -120,16 +137,7 @@ class CustomSerializationSchemeDriverTest {
class WriteTxToLedgerFlow(val counterparty: Party, val notary: Party) : FlowLogic<SecureHash>() {
@Suspendable
override fun call(): SecureHash {
val outputState = TransactionState(
data = DummyContract.DummyState(),
contract = DummyContract::class.java.name,
notary = notary,
constraint = AlwaysAcceptAttachmentConstraint
)
val builder = TransactionBuilder()
.addOutputState(outputState)
.addCommand(DummyCommandData, counterparty.owningKey)
val wireTx = builder.toWireTransaction(serviceHub, KryoScheme.SCHEME_ID)
val wireTx = createWireTx(serviceHub, notary, counterparty.owningKey, KryoScheme.SCHEME_ID)
val partSignedTx = signWireTx(wireTx)
val session = initiateFlow(counterparty)
val fullySignedTx = subFlow(CollectSignaturesFlow(partSignedTx, setOf(session)))
@ -174,17 +182,7 @@ class CustomSerializationSchemeDriverTest {
class CheckComponentGroupsFlow(val notary: Party) : FlowLogic<Boolean>() {
@Suspendable
override fun call(): Boolean {
val outputState = TransactionState(
data = DummyContract.DummyState(),
contract = DummyContract::class.java.name,
notary = notary,
constraint = AlwaysAcceptAttachmentConstraint
)
val builder = TransactionBuilder()
.addOutputState(outputState)
.addCommand(DummyCommandData, notary.owningKey)
val wtx = builder.toWireTransaction(serviceHub, KryoScheme.SCHEME_ID)
val wtx = createWireTx(serviceHub, notary, notary.owningKey, KryoScheme.SCHEME_ID)
var success = true
for (group in wtx.componentGroups) {
//Component groups are lazily serialized as we iterate through.
@ -230,23 +228,21 @@ class CustomSerializationSchemeDriverTest {
class SendFlow(val counterparty: Party) : FlowLogic<Boolean>() {
@Suspendable
override fun call(): Boolean {
val outputState = TransactionState(
data = DummyContract.DummyState(),
contract = DummyContract::class.java.name,
notary = counterparty,
constraint = AlwaysAcceptAttachmentConstraint
)
val builder = TransactionBuilder()
.addOutputState(outputState)
.addCommand(DummyCommandData, counterparty.owningKey)
val wtx = builder.toWireTransaction(serviceHub, KryoScheme.SCHEME_ID)
val wtx = createWireTx(serviceHub, counterparty, counterparty.owningKey, KryoScheme.SCHEME_ID)
val session = initiateFlow(counterparty)
session.send(wtx)
return session.receive<Boolean>().unwrap {it}
}
}
@StartableByRPC
class CreateWireTxFlow(val counterparty: Party) : FlowLogic<WireTransaction>() {
@Suspendable
override fun call(): WireTransaction {
return createWireTx(serviceHub, counterparty, counterparty.owningKey, KryoScheme.SCHEME_ID)
}
}
@InitiatedBy(SendFlow::class)
class ReceiveFlow(private val session: FlowSession): FlowLogic<Unit>() {
@Suspendable

View File

@ -0,0 +1,62 @@
package net.corda.node
import net.corda.core.crypto.SecureHash
import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.deserialize
import net.corda.node.CustomSerializationSchemeDriverTest.CreateWireTxFlow
import net.corda.node.CustomSerializationSchemeDriverTest.WriteTxToLedgerFlow
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.node.internal.CustomCordapp
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.InternalMockNodeParameters
import net.corda.testing.node.internal.enclosedCordapp
import net.corda.testing.node.internal.startFlow
import org.junit.After
import org.junit.Before
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
class CustomSerializationSchemeMockNetworkTest {
private lateinit var mockNetwork : InternalMockNetwork
val customSchemeCordapp: CustomCordapp = CustomSerializationSchemeDriverTest().enclosedCordapp()
@Before
fun setup() {
mockNetwork = InternalMockNetwork(cordappsForAllNodes = listOf(customSchemeCordapp))
}
@After
fun shutdown() {
mockNetwork.stopNodes()
}
@Test(timeout = 300_000)
fun `transactions network parameter hash is correct`() {
val alice = mockNetwork.createNode(InternalMockNodeParameters(legalName = ALICE_NAME))
val bob = mockNetwork.createNode(InternalMockNodeParameters(legalName = BOB_NAME))
val flow = alice.services.startFlow (CreateWireTxFlow(bob.info.legalIdentities.single()))
mockNetwork.runNetwork()
val wireTx = flow.resultFuture.get()
/** The NetworkParmeters is the last component in the list of component groups. If we ever change this this
* in [net.corda.core.internal.createComponentGroups] this test will need to be updated.*/
val serializedHash = SerializedBytes<SecureHash>(wireTx.componentGroups.last().components.single().bytes)
assertEquals(alice.internals.networkParametersStorage.defaultHash, serializedHash.deserialize())
}
@Test(timeout = 300_000)
fun `transaction can be written to the ledger`() {
val alice = mockNetwork.createNode(InternalMockNodeParameters(legalName = ALICE_NAME))
val bob = mockNetwork.createNode(InternalMockNodeParameters(legalName = BOB_NAME))
val flow = alice.services.startFlow (WriteTxToLedgerFlow(bob.info.legalIdentities.single(),
mockNetwork.notaryNodes.single().info.legalIdentities.single()))
mockNetwork.runNetwork()
val txId = flow.resultFuture.get()
val getTxFlow = bob.services.startFlow(CustomSerializationSchemeDriverTest.GetTxFromDBFlow(txId))
mockNetwork.runNetwork()
assertNotNull(getTxFlow.resultFuture.get())
}
}

View File

@ -20,17 +20,28 @@ import java.time.Instant
class MockNetworkParametersStorage(private var currentParameters: NetworkParameters = testNetworkParameters(modifiedTime = Instant.MIN)) : NetworkParametersStorage {
private val hashToParametersMap: HashMap<SecureHash, NetworkParameters> = HashMap()
private val hashToSignedParametersMap: HashMap<SecureHash, SignedNetworkParameters> = HashMap()
override var currentHash = currentParameters.computeHash()
override val defaultHash: SecureHash get() = currentHash
init {
storeCurrentParameters()
}
private fun NetworkParameters.computeHash(): SecureHash {
return withTestSerializationEnvIfNotSet {
this.serialize().hash
}
}
fun setCurrentParametersUnverified(networkParameters: NetworkParameters) {
currentParameters = networkParameters
currentHash = currentParameters.computeHash()
storeCurrentParameters()
}
override fun setCurrentParameters(currentSignedParameters: SignedDataWithCert<NetworkParameters>, trustRoots: Set<X509Certificate>) {
setCurrentParametersUnverified(currentSignedParameters.verifiedNetworkParametersCert(trustRoots))
currentParameters = currentSignedParameters.verifiedNetworkParametersCert(trustRoots)
currentHash = currentSignedParameters.raw.hash
storeCurrentParameters()
}
override fun lookupSigned(hash: SecureHash): SignedDataWithCert<NetworkParameters>? {
@ -39,13 +50,6 @@ class MockNetworkParametersStorage(private var currentParameters: NetworkParamet
override fun hasParameters(hash: SecureHash): Boolean = hash in hashToParametersMap
override val currentHash: SecureHash
get() {
return withTestSerializationEnvIfNotSet {
currentParameters.serialize().hash
}
}
override val defaultHash: SecureHash get() = currentHash
override fun lookup(hash: SecureHash): NetworkParameters? = hashToParametersMap[hash]
override fun getEpochFromHash(hash: SecureHash): Int? = lookup(hash)?.epoch
override fun saveParameters(signedNetworkParameters: SignedDataWithCert<NetworkParameters>) {