From 7ce8d7a8781e5f9df625d506870bd85c9ab4cb53 Mon Sep 17 00:00:00 2001 From: renlulu Date: Thu, 22 Mar 2018 21:45:02 +0800 Subject: [PATCH 1/3] SUBMISSION - Remove repeated code (#2864) --- .../kotlin/net/corda/node/services/schema/NodeSchemaService.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt b/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt index d874e838e6..eea216eff5 100644 --- a/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt +++ b/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt @@ -45,7 +45,6 @@ class NodeSchemaService(extraSchemas: Set = emptySet(), includeNot NodeAttachmentService.DBAttachment::class.java, P2PMessagingClient.ProcessedMessage::class.java, P2PMessagingClient.RetryMessage::class.java, - NodeAttachmentService.DBAttachment::class.java, PersistentIdentityService.PersistentIdentity::class.java, PersistentIdentityService.PersistentIdentityNames::class.java, ContractUpgradeServiceImpl.DBContractUpgrade::class.java From 620ba1e8a2e6e82aa3bc3dd2ecba9dafd2f48b00 Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Thu, 22 Mar 2018 14:08:07 +0000 Subject: [PATCH 2/3] Integration test for network parameter updates and improved logging (#2863) --- .../nodeapi/internal/network/NetworkMap.kt | 9 ++- .../node/services/network/NetworkMapTest.kt | 64 ++++++++++++++++--- .../node/internal/NetworkParametersReader.kt | 4 +- .../node/services/network/NetworkMapClient.kt | 14 ++-- .../services/network/NetworkMapUpdater.kt | 17 +++-- .../services/network/NetworkMapUpdaterTest.kt | 8 +-- .../node/internal/network/NetworkMapServer.kt | 4 -- 7 files changed, 87 insertions(+), 33 deletions(-) diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt index 0433aed3f2..e86d1e7da1 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt @@ -31,7 +31,14 @@ data class NetworkMap( val nodeInfoHashes: List, val networkParameterHash: SecureHash, val parametersUpdate: ParametersUpdate? -) +) { + override fun toString(): String { + return """${NetworkMap::class.java.simpleName}(nodeInfoHashes= +${nodeInfoHashes.joinToString("\n")} +networkParameterHash=$networkParameterHash +parametersUpdate=$parametersUpdate)""" + } +} /** * Data class representing scheduled network parameters update. diff --git a/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt index e570038e5f..521edc9bc5 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt @@ -2,35 +2,34 @@ package net.corda.node.services.network import net.corda.cordform.CordformNode import net.corda.core.crypto.random63BitValue +import net.corda.core.internal.* import net.corda.core.internal.concurrent.transpose -import net.corda.core.internal.div -import net.corda.core.internal.exists -import net.corda.core.internal.list -import net.corda.core.internal.readObject +import net.corda.core.messaging.ParametersUpdateInfo import net.corda.core.node.NodeInfo +import net.corda.core.serialization.serialize import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.seconds import net.corda.nodeapi.internal.network.NETWORK_PARAMS_FILE_NAME +import net.corda.nodeapi.internal.network.NETWORK_PARAMS_UPDATE_FILE_NAME import net.corda.nodeapi.internal.network.SignedNetworkParameters import net.corda.testing.common.internal.testNetworkParameters -import net.corda.testing.core.ALICE_NAME -import net.corda.testing.core.BOB_NAME -import net.corda.testing.core.SerializationEnvironmentRule +import net.corda.testing.core.* import net.corda.testing.driver.NodeHandle -import net.corda.testing.driver.PortAllocation +import net.corda.testing.driver.internal.NodeHandleInternal import net.corda.testing.driver.internal.RandomFree import net.corda.testing.node.internal.CompatibilityZoneParams import net.corda.testing.node.internal.internalDriver import net.corda.testing.node.internal.network.NetworkMapServer import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy import org.junit.After +import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule import org.junit.Test import java.net.URL import java.time.Instant import kotlin.streams.toList -import kotlin.test.assertEquals class NetworkMapTest { @Rule @@ -57,6 +56,53 @@ class NetworkMapTest { networkMapServer.close() } + @Test + fun `parameters update test`() { + internalDriver( + portAllocation = portAllocation, + compatibilityZone = compatibilityZone, + initialiseSerialization = false, + notarySpecs = emptyList() + ) { + val alice = startNode(providedName = ALICE_NAME).getOrThrow() as NodeHandleInternal + val nextParams = networkMapServer.networkParameters.copy(epoch = 3, modifiedTime = Instant.ofEpochMilli(random63BitValue())) + val nextHash = nextParams.serialize().hash + val snapshot = alice.rpc.networkParametersFeed().snapshot + val updates = alice.rpc.networkParametersFeed().updates.bufferUntilSubscribed() + assertEquals(null, snapshot) + assertThat(updates.isEmpty) + networkMapServer.scheduleParametersUpdate(nextParams, "Next parameters", Instant.ofEpochMilli(random63BitValue())) + // Wait for network map client to poll for the next update. + Thread.sleep(cacheTimeout.toMillis() * 2) + val laterParams = networkMapServer.networkParameters.copy(epoch = 4, modifiedTime = Instant.ofEpochMilli(random63BitValue())) + val laterHash = laterParams.serialize().hash + networkMapServer.scheduleParametersUpdate(laterParams, "Another update", Instant.ofEpochMilli(random63BitValue())) + Thread.sleep(cacheTimeout.toMillis() * 2) + updates.expectEvents(isStrict = false) { + sequence( + expect { update: ParametersUpdateInfo -> + assertEquals(update.description, "Next parameters") + assertEquals(update.hash, nextHash) + assertEquals(update.parameters, nextParams) + }, + expect { update: ParametersUpdateInfo -> + assertEquals(update.description, "Another update") + assertEquals(update.hash, laterHash) + assertEquals(update.parameters, laterParams) + } + ) + } + // This should throw, because the nextHash has been replaced by laterHash + assertThatThrownBy { alice.rpc.acceptNewNetworkParameters(nextHash) }.hasMessageContaining("Refused to accept parameters with hash") + alice.rpc.acceptNewNetworkParameters(laterHash) + assertEquals(laterHash, networkMapServer.latestParametersAccepted(alice.nodeInfo.legalIdentities.first().owningKey)) + networkMapServer.advertiseNewParameters() + val networkParameters = (alice.configuration.baseDirectory / NETWORK_PARAMS_UPDATE_FILE_NAME) + .readObject().verified() + assertEquals(networkParameters, laterParams) + } + } + @Test fun `node correctly downloads and saves network parameters file on startup`() { internalDriver( diff --git a/node/src/main/kotlin/net/corda/node/internal/NetworkParametersReader.kt b/node/src/main/kotlin/net/corda/node/internal/NetworkParametersReader.kt index bc5073ff4e..b872a0f919 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NetworkParametersReader.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NetworkParametersReader.kt @@ -38,8 +38,7 @@ class NetworkParametersReader(private val trustRoot: X509Certificate, // you get them from network map, but you have to run the approval step. if (signedParametersFromFile == null) { // Node joins for the first time. downloadParameters(trustRoot, advertisedParametersHash) - } - else if (signedParametersFromFile.raw.hash == advertisedParametersHash) { // Restarted with the same parameters. + } else if (signedParametersFromFile.raw.hash == advertisedParametersHash) { // Restarted with the same parameters. signedParametersFromFile.verifiedNetworkMapCert(trustRoot) } else { // Update case. readParametersUpdate(advertisedParametersHash, signedParametersFromFile.raw.hash).verifiedNetworkMapCert(trustRoot) @@ -64,6 +63,7 @@ class NetworkParametersReader(private val trustRoot: X509Certificate, "Please update node to use correct network parameters file.") } parametersUpdateFile.moveTo(networkParamsFile, StandardCopyOption.REPLACE_EXISTING) + logger.info("Scheduled update to network parameters has occurred - node now updated to these new parameters.") return signedUpdatedParameters } diff --git a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapClient.kt b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapClient.kt index 617a03a39f..4508b7753b 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapClient.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapClient.kt @@ -2,7 +2,9 @@ package net.corda.node.services.network import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SignedData -import net.corda.core.internal.* +import net.corda.core.internal.openHttpConnection +import net.corda.core.internal.post +import net.corda.core.internal.responseAs import net.corda.core.node.NodeInfo import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize @@ -11,7 +13,10 @@ import net.corda.core.utilities.seconds import net.corda.core.utilities.trace import net.corda.node.utilities.registration.cacheControl import net.corda.nodeapi.internal.SignedNodeInfo -import net.corda.nodeapi.internal.network.* +import net.corda.nodeapi.internal.network.NetworkMap +import net.corda.nodeapi.internal.network.SignedNetworkMap +import net.corda.nodeapi.internal.network.SignedNetworkParameters +import net.corda.nodeapi.internal.network.verifiedNetworkMapCert import java.io.BufferedReader import java.net.URL import java.security.cert.X509Certificate @@ -44,10 +49,7 @@ class NetworkMapClient(compatibilityZoneURL: URL, val trustedRoot: X509Certifica val signedNetworkMap = connection.responseAs() val networkMap = signedNetworkMap.verifiedNetworkMapCert(trustedRoot) val timeout = connection.cacheControl().maxAgeSeconds().seconds - logger.trace { - "Fetched network map update from $networkMapUrl successfully, retrieved ${networkMap.nodeInfoHashes.size} " + - "node info hashes. Node Info hashes:\n${networkMap.nodeInfoHashes.joinToString("\n")}" - } + logger.trace { "Fetched network map update from $networkMapUrl successfully: $networkMap" } return NetworkMapResponse(networkMap, timeout) } diff --git a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapUpdater.kt b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapUpdater.kt index 9013785798..8a4726df50 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapUpdater.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapUpdater.kt @@ -147,12 +147,13 @@ class NetworkMapUpdater(private val networkMapCache: NetworkMapCacheInternal, // This update was handled already. return } - val newParameters = networkMapClient.getNetworkParameters(update.newParametersHash) - logger.info("Downloaded new network parameters: $newParameters from the update: $update") - newNetworkParameters = Pair(update, newParameters) + val newSignedNetParams = networkMapClient.getNetworkParameters(update.newParametersHash) + val newNetParams = newSignedNetParams.verifiedNetworkMapCert(networkMapClient.trustedRoot) + logger.info("Downloaded new network parameters: $newNetParams from the update: $update") + newNetworkParameters = Pair(update, newSignedNetParams) val updateInfo = ParametersUpdateInfo( update.newParametersHash, - newParameters.verifiedNetworkMapCert(networkMapClient.trustedRoot), + newNetParams, update.description, update.updateDeadline) parametersUpdatesTrack.onNext(updateInfo) @@ -162,15 +163,17 @@ class NetworkMapUpdater(private val networkMapCache: NetworkMapCacheInternal, networkMapClient ?: throw IllegalStateException("Network parameters updates are not support without compatibility zone configured") // TODO This scenario will happen if node was restarted and didn't download parameters yet, but we accepted them. // Add persisting of newest parameters from update. - val (_, newParams) = requireNotNull(newNetworkParameters) { "Couldn't find parameters update for the hash: $parametersHash" } + val (update, signedNewNetParams) = requireNotNull(newNetworkParameters) { "Couldn't find parameters update for the hash: $parametersHash" } // We should check that we sign the right data structure hash. - val newParametersHash = newParams.verifiedNetworkMapCert(networkMapClient.trustedRoot).serialize().hash + val newNetParams = signedNewNetParams.verifiedNetworkMapCert(networkMapClient.trustedRoot) + val newParametersHash = newNetParams.serialize().hash if (parametersHash == newParametersHash) { // The latest parameters have priority. - newParams.serialize() + signedNewNetParams.serialize() .open() .copyTo(baseDirectory / NETWORK_PARAMS_UPDATE_FILE_NAME, StandardCopyOption.REPLACE_EXISTING) networkMapClient.ackNetworkParametersUpdate(sign(parametersHash)) + logger.info("Accepted network parameter update $update: $newNetParams") } else { throw IllegalArgumentException("Refused to accept parameters with hash $parametersHash because network map " + "advertises update with hash $newParametersHash. Please check newest version") diff --git a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt index 2f6535a74f..9fc5698821 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapUpdaterTest.kt @@ -205,10 +205,10 @@ class NetworkMapUpdaterTest { updates.expectEvents(isStrict = false) { sequence( expect { update: ParametersUpdateInfo -> - assertThat(update.updateDeadline == updateDeadline) - assertThat(update.description == "Test update") - assertThat(update.hash == newParameters.serialize().hash) - assertThat(update.parameters == newParameters) + assertEquals(update.updateDeadline, updateDeadline) + assertEquals(update.description,"Test update") + assertEquals(update.hash, newParameters.serialize().hash) + assertEquals(update.parameters, newParameters) } ) } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/network/NetworkMapServer.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/network/NetworkMapServer.kt index 763cce2bf3..4285c983c3 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/network/NetworkMapServer.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/network/NetworkMapServer.kt @@ -44,10 +44,6 @@ class NetworkMapServer(private val cacheTimeout: Duration, private val server: Server var networkParameters: NetworkParameters = stubNetworkParameters - set(networkParameters) { - check(field == stubNetworkParameters) { "Network parameters can be set only once" } - field = networkParameters - } private val service = InMemoryNetworkMapService() private var parametersUpdate: ParametersUpdate? = null private var nextNetworkParameters: NetworkParameters? = null From 7f2a056c450745391f7bd32a3aafc2e6f38dc2dc Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Thu, 22 Mar 2018 14:14:49 +0000 Subject: [PATCH 3/3] Merge cleanup --- .../corda/node/services/network/NetworkMapTest.kt | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt index 9b2dbebdc9..c9a3f6964d 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt @@ -19,7 +19,6 @@ import net.corda.core.node.NodeInfo import net.corda.core.serialization.serialize import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.seconds -import net.corda.core.serialization.serialize import net.corda.nodeapi.internal.network.NETWORK_PARAMS_FILE_NAME import net.corda.nodeapi.internal.network.NETWORK_PARAMS_UPDATE_FILE_NAME import net.corda.nodeapi.internal.network.SignedNetworkParameters @@ -34,15 +33,10 @@ import net.corda.testing.internal.toDatabaseSchemaName import net.corda.testing.node.internal.CompatibilityZoneParams import net.corda.testing.node.internal.internalDriver import net.corda.testing.node.internal.network.NetworkMapServer -import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThat -import org.junit.* import org.assertj.core.api.Assertions.assertThatThrownBy -import org.junit.After +import org.junit.* import org.junit.Assert.assertEquals -import org.junit.Before -import org.junit.Rule -import org.junit.Test import java.net.URL import java.time.Instant import kotlin.streams.toList @@ -51,9 +45,12 @@ class NetworkMapTest : IntegrationTest() { companion object { @ClassRule @JvmField - val databaseSchemas = IntegrationTestSchemas(ALICE_NAME.toDatabaseSchemaName(), BOB_NAME.toDatabaseSchemaName(), + val databaseSchemas = IntegrationTestSchemas( + ALICE_NAME.toDatabaseSchemaName(), + BOB_NAME.toDatabaseSchemaName(), DUMMY_NOTARY_NAME.toDatabaseSchemaName()) } + @Rule @JvmField val testSerialization = SerializationEnvironmentRule(true)