mirror of
https://github.com/corda/corda.git
synced 2025-06-12 04:08:26 +00:00
ENT-2666: Don't check for network parameter currentness for now (#4322)
* ENT-2666: Don't check for network parameter currentness for now * Add check for parameters null when version >= 4 * Add check that parameters are known to the node/network * Add test
This commit is contained in:
committed by
Katarzyna Streich
parent
171bba1d30
commit
0925008f9e
@ -212,11 +212,6 @@ abstract class SignTransactionFlow @JvmOverloads constructor(val otherSideSessio
|
|||||||
progressTracker.currentStep = RECEIVING
|
progressTracker.currentStep = RECEIVING
|
||||||
// Receive transaction and resolve dependencies, check sufficient signatures is disabled as we don't have all signatures.
|
// Receive transaction and resolve dependencies, check sufficient signatures is disabled as we don't have all signatures.
|
||||||
val stx = subFlow(ReceiveTransactionFlow(otherSideSession, checkSufficientSignatures = false))
|
val stx = subFlow(ReceiveTransactionFlow(otherSideSession, checkSufficientSignatures = false))
|
||||||
// TODO ENT-2666: Have time period for checking the parameters (because of the delay of propagation of new network data).
|
|
||||||
check(stx.networkParametersHash == serviceHub.networkParametersStorage.currentHash) {
|
|
||||||
"Received transaction for signing with invalid network parameters hash: ${stx.networkParametersHash}." +
|
|
||||||
"Node's parameters hash: ${serviceHub.networkParametersStorage.currentHash}"
|
|
||||||
}
|
|
||||||
// Receive the signing key that the party requesting the signature expects us to sign with. Having this provided
|
// Receive the signing key that the party requesting the signature expects us to sign with. Having this provided
|
||||||
// means we only have to check we own that one key, rather than matching all keys in the transaction against all
|
// means we only have to check we own that one key, rather than matching all keys in the transaction against all
|
||||||
// keys we own.
|
// keys we own.
|
||||||
|
@ -3,6 +3,7 @@ package net.corda.core.flows
|
|||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import net.corda.core.contracts.*
|
import net.corda.core.contracts.*
|
||||||
import net.corda.core.internal.ResolveTransactionsFlow
|
import net.corda.core.internal.ResolveTransactionsFlow
|
||||||
|
import net.corda.core.internal.checkParameterHash
|
||||||
import net.corda.core.internal.pushToLoggingContext
|
import net.corda.core.internal.pushToLoggingContext
|
||||||
import net.corda.core.node.StatesToRecord
|
import net.corda.core.node.StatesToRecord
|
||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
@ -41,6 +42,7 @@ open class ReceiveTransactionFlow @JvmOverloads constructor(private val otherSid
|
|||||||
val stx = otherSideSession.receive<SignedTransaction>().unwrap {
|
val stx = otherSideSession.receive<SignedTransaction>().unwrap {
|
||||||
it.pushToLoggingContext()
|
it.pushToLoggingContext()
|
||||||
logger.info("Received transaction acknowledgement request from party ${otherSideSession.counterparty}.")
|
logger.info("Received transaction acknowledgement request from party ${otherSideSession.counterparty}.")
|
||||||
|
checkParameterHash(it.networkParametersHash)
|
||||||
subFlow(ResolveTransactionsFlow(it, otherSideSession))
|
subFlow(ResolveTransactionsFlow(it, otherSideSession))
|
||||||
logger.info("Transaction dependencies resolution completed.")
|
logger.info("Transaction dependencies resolution completed.")
|
||||||
try {
|
try {
|
||||||
|
@ -5,6 +5,7 @@ import net.corda.core.contracts.*
|
|||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.componentHash
|
import net.corda.core.crypto.componentHash
|
||||||
import net.corda.core.crypto.sha256
|
import net.corda.core.crypto.sha256
|
||||||
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.serialization.*
|
import net.corda.core.serialization.*
|
||||||
import net.corda.core.transactions.*
|
import net.corda.core.transactions.*
|
||||||
@ -157,3 +158,20 @@ fun createComponentGroups(inputs: List<StateRef>,
|
|||||||
data class SerializedStateAndRef(val serializedState: SerializedBytes<TransactionState<ContractState>>, val ref: StateRef) {
|
data class SerializedStateAndRef(val serializedState: SerializedBytes<TransactionState<ContractState>>, val ref: StateRef) {
|
||||||
fun toStateAndRef(): StateAndRef<ContractState> = StateAndRef(serializedState.deserialize(), ref)
|
fun toStateAndRef(): StateAndRef<ContractState> = StateAndRef(serializedState.deserialize(), ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check that network parameters hash on this transaction is the current hash for the network. */
|
||||||
|
fun FlowLogic<*>.checkParameterHash(networkParametersHash: SecureHash?) {
|
||||||
|
// Transactions created on Corda 3.x or below do not contain network parameters,
|
||||||
|
// so no checking is done until the minimum platform version is at least 4.
|
||||||
|
if (networkParametersHash == null) {
|
||||||
|
if (serviceHub.networkParameters.minimumPlatformVersion < 4) return
|
||||||
|
else throw IllegalArgumentException("Transaction for notarisation doesn't contain network parameters hash.")
|
||||||
|
} else {
|
||||||
|
serviceHub.networkParametersStorage.lookup(networkParametersHash) ?: throw IllegalArgumentException("Transaction for notarisation contains unknown parameters hash: $networkParametersHash")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: [ENT-2666] Implement network parameters fuzzy checking. By design in Corda network we have propagation time delay.
|
||||||
|
// We will never end up in perfect synchronization with all the nodes. However, network parameters update process
|
||||||
|
// lets us predict what is the reasonable time window for changing parameters on most of the nodes.
|
||||||
|
// For now we don't check whether the attached network parameters match the current ones.
|
||||||
|
}
|
@ -17,6 +17,7 @@ import net.corda.core.flows.NotaryFlow
|
|||||||
import net.corda.core.flows.WaitTimeUpdate
|
import net.corda.core.flows.WaitTimeUpdate
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.internal.MIN_PLATFORM_VERSION_FOR_BACKPRESSURE_MESSAGE
|
import net.corda.core.internal.MIN_PLATFORM_VERSION_FOR_BACKPRESSURE_MESSAGE
|
||||||
|
import net.corda.core.internal.checkParameterHash
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
import net.corda.core.utilities.unwrap
|
import net.corda.core.utilities.unwrap
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
@ -94,7 +95,7 @@ abstract class NotaryServiceFlow(val otherSideSession: FlowSession, val service:
|
|||||||
val transaction = extractParts(requestPayload)
|
val transaction = extractParts(requestPayload)
|
||||||
transactionId = transaction.id
|
transactionId = transaction.id
|
||||||
checkNotary(transaction.notary)
|
checkNotary(transaction.notary)
|
||||||
checkParametersHash(transaction.networkParametersHash)
|
checkParameterHash(transaction.networkParametersHash)
|
||||||
checkInputs(transaction.inputs + transaction.references)
|
checkInputs(transaction.inputs + transaction.references)
|
||||||
return transaction
|
return transaction
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@ -122,21 +123,6 @@ abstract class NotaryServiceFlow(val otherSideSession: FlowSession, val service:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that network parameters hash on this transaction is the current hash for the network.
|
|
||||||
*/
|
|
||||||
// TODO ENT-2666 Implement network parameters fuzzy checking. By design in Corda network we have propagation time delay.
|
|
||||||
// We will never end up in perfect synchronization with all the nodes. However, network parameters update process
|
|
||||||
// lets us predict what is the reasonable time window for changing parameters on most of the nodes.
|
|
||||||
@Suspendable
|
|
||||||
protected fun checkParametersHash(networkParametersHash: SecureHash?) {
|
|
||||||
if (networkParametersHash == null && serviceHub.networkParameters.minimumPlatformVersion < 4) return
|
|
||||||
val notaryParametersHash = serviceHub.networkParametersStorage.currentHash
|
|
||||||
require (notaryParametersHash == networkParametersHash) {
|
|
||||||
"Transaction for notarisation was tagged with parameters with hash: $networkParametersHash, but current network parameters are: $notaryParametersHash"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Verifies that the correct notarisation request was signed by the counterparty. */
|
/** Verifies that the correct notarisation request was signed by the counterparty. */
|
||||||
private fun validateRequestSignature(request: NotarisationRequest, signature: NotarisationRequestSignature) {
|
private fun validateRequestSignature(request: NotarisationRequest, signature: NotarisationRequestSignature) {
|
||||||
val requestingParty = otherSideSession.counterparty
|
val requestingParty = otherSideSession.counterparty
|
||||||
|
@ -22,6 +22,7 @@ import net.corda.testing.node.internal.*
|
|||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Ignore
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ class NotaryServiceTests {
|
|||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
val ex = assertFailsWith<NotaryException> { future.getOrThrow() }
|
val ex = assertFailsWith<NotaryException> { future.getOrThrow() }
|
||||||
val notaryError = ex.error as NotaryError.TransactionInvalid
|
val notaryError = ex.error as NotaryError.TransactionInvalid
|
||||||
assertThat(notaryError.cause).hasMessageContaining("Transaction for notarisation was tagged with parameters with hash: null")
|
assertThat(notaryError.cause).hasMessageContaining("Transaction for notarisation doesn't contain network parameters hash.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -73,8 +74,7 @@ class NotaryServiceTests {
|
|||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
val ex = assertFailsWith<NotaryException> { future.getOrThrow() }
|
val ex = assertFailsWith<NotaryException> { future.getOrThrow() }
|
||||||
val notaryError = ex.error as NotaryError.TransactionInvalid
|
val notaryError = ex.error as NotaryError.TransactionInvalid
|
||||||
assertThat(notaryError.cause).hasMessageContaining("Transaction for notarisation was tagged with parameters with hash: $hash, " +
|
assertThat(notaryError.cause).hasMessageContaining("Transaction for notarisation contains unknown parameters hash: $hash")
|
||||||
"but current network parameters are: ${notaryServices.networkParametersStorage.currentHash}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal companion object {
|
internal companion object {
|
||||||
|
@ -119,7 +119,7 @@ class ValidatingNotaryServiceTests {
|
|||||||
val future = runNotaryClient(stx)
|
val future = runNotaryClient(stx)
|
||||||
val ex = assertFailsWith(NotaryException::class) { future.getOrThrow() }
|
val ex = assertFailsWith(NotaryException::class) { future.getOrThrow() }
|
||||||
val notaryError = ex.error as NotaryError.TransactionInvalid
|
val notaryError = ex.error as NotaryError.TransactionInvalid
|
||||||
assertThat(notaryError.cause).hasMessageContaining("Transaction for notarisation was tagged with parameters with hash: null")
|
assertThat(notaryError.cause).hasMessageContaining("Transaction for notarisation doesn't contain network parameters hash.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Reference in New Issue
Block a user