[CORDA-2387]: Seeing warnings for "Double insert in net.corda.node.utilities.AppendOnlyPersistentMap" (fixed) (#4499)

* [CORDA-2387]: Reproduced the issue in a test.

* [CORDA-2387]: Fixed.

* [CORDA-2387]: Fixed.
This commit is contained in:
Michele Sollecito 2019-01-03 17:59:34 +00:00 committed by GitHub
parent f590300cdf
commit 5d3b24dcfa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 4 deletions

View File

@ -43,6 +43,4 @@ private fun FlowHandle<*>.waitForCompletion() {
} catch (e: Exception) {
// This is expected to throw an exception, using getOrThrow() just to wait until done.
}
}
private fun NodeHandle.logFile(): File = (baseDirectory / "logs").toFile().walk().filter { it.name.startsWith("node-") && it.extension == "log" }.single()
}

View File

@ -0,0 +1,79 @@
package net.corda.node.logging
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.concurrent.CordaFuture
import net.corda.core.contracts.Amount
import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.Party
import net.corda.core.messaging.startFlow
import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS
import net.corda.finance.flows.AbstractCashFlow
import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.Permissions.Companion.all
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.node.User
import net.corda.testing.node.internal.cordappWithPackages
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import java.util.*
import java.util.concurrent.CompletableFuture.allOf
class IssueCashLoggingTests {
private val UNSIGNED_FINANCE_CORDAPP = cordappWithPackages("net.corda.finance")
@Test
fun `issuing and sending cash as payment do not result in duplicate insertion warnings`() {
val user = User("mark", "dadada", setOf(all()))
driver(DriverParameters(cordappsForAllNodes = setOf(UNSIGNED_FINANCE_CORDAPP))) {
val nodeA = startNode(rpcUsers = listOf(user)).getOrThrow()
val nodeB = startNode().getOrThrow()
val amount = 1.DOLLARS
val ref = OpaqueBytes.of(0)
val recipient = nodeB.nodeInfo.legalIdentities[0]
nodeA.rpc.startFlow(::CashIssueAndPaymentFlow, amount, ref, recipient, false, defaultNotaryIdentity).returnValue.getOrThrow()
val linesWithDuplicateInsertionWarningsInA = nodeA.logFile().useLines { lines -> lines.filter(String::containsDuplicateInsertWarning).toList() }
val linesWithDuplicateInsertionWarningsInB = nodeB.logFile().useLines { lines -> lines.filter(String::containsDuplicateInsertWarning).toList() }
assertThat(linesWithDuplicateInsertionWarningsInA).isEmpty()
assertThat(linesWithDuplicateInsertionWarningsInB).isEmpty()
}
}
@StartableByRPC
class CashIssueAndPaymentFlow(val amount: Amount<Currency>,
val issueRef: OpaqueBytes,
val recipient: Party,
val anonymous: Boolean,
val notary: Party,
progressTracker: ProgressTracker) : AbstractCashFlow<AbstractCashFlow.Result>(progressTracker) {
constructor(amount: Amount<Currency>,
issueRef: OpaqueBytes,
recipient: Party,
anonymous: Boolean,
notary: Party) : this(amount, issueRef, recipient, anonymous, notary, tracker())
constructor(request: IssueAndPaymentRequest) : this(request.amount, request.issueRef, request.recipient, request.anonymous, request.notary, tracker())
@Suspendable
override fun call(): Result {
subFlow(CashIssueFlow(amount, issueRef, notary))
return subFlow(CashPaymentFlow(amount, recipient, anonymous))
}
@CordaSerializable
class IssueAndPaymentRequest(amount: Amount<Currency>, val issueRef: OpaqueBytes, val recipient: Party, val notary: Party, val anonymous: Boolean) : AbstractRequest(amount)
}
}
private fun String.containsDuplicateInsertWarning(): Boolean = contains("Double insert") && contains("not inserting the second time")

View File

@ -0,0 +1,7 @@
package net.corda.node.logging
import net.corda.core.internal.div
import net.corda.testing.driver.NodeHandle
import java.io.File
fun NodeHandle.logFile(): File = (baseDirectory / "logs").toFile().walk().filter { it.name.startsWith("node-") && it.extension == "log" }.single()

View File

@ -72,7 +72,7 @@ interface IdentityServiceInternal : IdentityService {
}
// Ensure we record the first identity of the same name, first
val wellKnownCert = identityCertChain.single { CertRole.extract(it)?.isWellKnown ?: false }
if (wellKnownCert != identity.certificate) {
if (wellKnownCert != identity.certificate && !isNewRandomIdentity) {
val idx = identityCertChain.lastIndexOf(wellKnownCert)
val firstPath = X509Utilities.buildCertPath(identityCertChain.slice(idx until identityCertChain.size))
verifyAndRegisterIdentity(trustAnchor, PartyAndCertificate(firstPath))