forked from corda/corda
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CORDA-1845: Check for min plaform version of 4 when building transact…
…ions with reference states (corda#3705) Also includes some minor cleanup brought up in a previous PR.
- Loading branch information
1 parent
d42b9f5
commit 994fe0d
Showing
9 changed files
with
198 additions
and
56 deletions.
There are no files selected for viewing
57 changes: 57 additions & 0 deletions
57
core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package net.corda.core.internal | ||
|
||
import net.corda.core.DeleteForDJVM | ||
import net.corda.core.cordapp.Cordapp | ||
import net.corda.core.cordapp.CordappConfig | ||
import net.corda.core.cordapp.CordappContext | ||
import net.corda.core.crypto.SecureHash | ||
import net.corda.core.flows.FlowLogic | ||
import net.corda.core.node.ServicesForResolution | ||
import net.corda.core.node.ZoneVersionTooLowException | ||
import net.corda.core.serialization.SerializationContext | ||
import net.corda.core.transactions.LedgerTransaction | ||
import net.corda.core.transactions.SignedTransaction | ||
import net.corda.core.transactions.TransactionBuilder | ||
import net.corda.core.transactions.WireTransaction | ||
import org.slf4j.MDC | ||
|
||
// *Internal* Corda-specific utilities | ||
|
||
fun ServicesForResolution.ensureMinimumPlatformVersion(requiredMinPlatformVersion: Int, feature: String) { | ||
val currentMinPlatformVersion = networkParameters.minimumPlatformVersion | ||
if (currentMinPlatformVersion < requiredMinPlatformVersion) { | ||
throw ZoneVersionTooLowException( | ||
"$feature requires all nodes on the Corda compatibility zone to be running at least platform version " + | ||
"$requiredMinPlatformVersion. The current zone is only enforcing a minimum platform version of " + | ||
"$currentMinPlatformVersion. Please contact your zone operator." | ||
) | ||
} | ||
} | ||
|
||
/** Provide access to internal method for AttachmentClassLoaderTests */ | ||
@DeleteForDJVM | ||
fun TransactionBuilder.toWireTransaction(services: ServicesForResolution, serializationContext: SerializationContext): WireTransaction { | ||
return toWireTransactionWithContext(services, serializationContext) | ||
} | ||
|
||
/** Provide access to internal method for AttachmentClassLoaderTests */ | ||
@DeleteForDJVM | ||
fun TransactionBuilder.toLedgerTransaction(services: ServicesForResolution, serializationContext: SerializationContext): LedgerTransaction { | ||
return toLedgerTransactionWithContext(services, serializationContext) | ||
} | ||
|
||
fun createCordappContext(cordapp: Cordapp, attachmentId: SecureHash?, classLoader: ClassLoader, config: CordappConfig): CordappContext { | ||
return CordappContext(cordapp, attachmentId, classLoader, config) | ||
} | ||
|
||
/** Checks if this flow is an idempotent flow. */ | ||
fun Class<out FlowLogic<*>>.isIdempotentFlow(): Boolean { | ||
return IdempotentFlow::class.java.isAssignableFrom(this) | ||
} | ||
|
||
/** | ||
* Ensures each log entry from the current thread will contain id of the transaction in the MDC. | ||
*/ | ||
internal fun SignedTransaction.pushToLoggingContext() { | ||
MDC.put("tx_id", id.toString()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
core/src/test/kotlin/net/corda/core/transactions/TransactionBuilderTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package net.corda.core.transactions | ||
|
||
import com.nhaarman.mockito_kotlin.doReturn | ||
import com.nhaarman.mockito_kotlin.whenever | ||
import net.corda.core.contracts.* | ||
import net.corda.core.cordapp.CordappProvider | ||
import net.corda.core.crypto.SecureHash | ||
import net.corda.core.node.ServicesForResolution | ||
import net.corda.core.node.ZoneVersionTooLowException | ||
import net.corda.testing.common.internal.testNetworkParameters | ||
import net.corda.testing.contracts.DummyContract | ||
import net.corda.testing.contracts.DummyState | ||
import net.corda.testing.core.DUMMY_NOTARY_NAME | ||
import net.corda.testing.core.DummyCommandData | ||
import net.corda.testing.core.SerializationEnvironmentRule | ||
import net.corda.testing.core.TestIdentity | ||
import net.corda.testing.internal.rigorousMock | ||
import org.assertj.core.api.Assertions.assertThat | ||
import org.assertj.core.api.Assertions.assertThatThrownBy | ||
import org.junit.Before | ||
import org.junit.Rule | ||
import org.junit.Test | ||
|
||
class TransactionBuilderTest { | ||
@Rule | ||
@JvmField | ||
val testSerialization = SerializationEnvironmentRule() | ||
|
||
private val notary = TestIdentity(DUMMY_NOTARY_NAME).party | ||
private val services = rigorousMock<ServicesForResolution>() | ||
private val contractAttachmentId = SecureHash.randomSHA256() | ||
|
||
@Before | ||
fun setup() { | ||
val cordappProvider = rigorousMock<CordappProvider>() | ||
doReturn(cordappProvider).whenever(services).cordappProvider | ||
doReturn(contractAttachmentId).whenever(cordappProvider).getContractAttachmentID(DummyContract.PROGRAM_ID) | ||
doReturn(testNetworkParameters()).whenever(services).networkParameters | ||
} | ||
|
||
@Test | ||
fun `bare minimum issuance tx`() { | ||
val outputState = TransactionState( | ||
data = DummyState(), | ||
contract = DummyContract.PROGRAM_ID, | ||
notary = notary, | ||
constraint = HashAttachmentConstraint(contractAttachmentId) | ||
) | ||
val builder = TransactionBuilder() | ||
.addOutputState(outputState) | ||
.addCommand(DummyCommandData, notary.owningKey) | ||
val wtx = builder.toWireTransaction(services) | ||
assertThat(wtx.outputs).containsOnly(outputState) | ||
assertThat(wtx.commands).containsOnly(Command(DummyCommandData, notary.owningKey)) | ||
} | ||
|
||
@Test | ||
fun `automatic hash constraint`() { | ||
val outputState = TransactionState(data = DummyState(), contract = DummyContract.PROGRAM_ID, notary = notary) | ||
val builder = TransactionBuilder() | ||
.addOutputState(outputState) | ||
.addCommand(DummyCommandData, notary.owningKey) | ||
val wtx = builder.toWireTransaction(services) | ||
assertThat(wtx.outputs).containsOnly(outputState.copy(constraint = HashAttachmentConstraint(contractAttachmentId))) | ||
} | ||
|
||
@Test | ||
fun `reference states`() { | ||
val referenceState = TransactionState(DummyState(), DummyContract.PROGRAM_ID, notary) | ||
val referenceStateRef = StateRef(SecureHash.randomSHA256(), 1) | ||
val builder = TransactionBuilder(notary) | ||
.addReferenceState(StateAndRef(referenceState, referenceStateRef).referenced()) | ||
.addOutputState(TransactionState(DummyState(), DummyContract.PROGRAM_ID, notary)) | ||
.addCommand(DummyCommandData, notary.owningKey) | ||
|
||
doReturn(testNetworkParameters(minimumPlatformVersion = 3)).whenever(services).networkParameters | ||
assertThatThrownBy { builder.toWireTransaction(services) } | ||
.isInstanceOf(ZoneVersionTooLowException::class.java) | ||
.hasMessageContaining("Reference states") | ||
|
||
doReturn(testNetworkParameters(minimumPlatformVersion = 4)).whenever(services).networkParameters | ||
val wtx = builder.toWireTransaction(services) | ||
assertThat(wtx.references).containsOnly(referenceStateRef) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.