mirror of
https://github.com/corda/corda.git
synced 2025-06-23 09:25:36 +00:00
CORDA-2871: Add a callback to ServicesForResolution to allow the Node to modify a LedgerTransaction object.
This commit is contained in:
@ -10,6 +10,7 @@ import net.corda.core.flows.ContractUpgradeFlow
|
|||||||
import net.corda.core.node.services.*
|
import net.corda.core.node.services.*
|
||||||
import net.corda.core.serialization.SerializeAsToken
|
import net.corda.core.serialization.SerializeAsToken
|
||||||
import net.corda.core.transactions.FilteredTransaction
|
import net.corda.core.transactions.FilteredTransaction
|
||||||
|
import net.corda.core.transactions.LedgerTransaction
|
||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
import net.corda.core.transactions.TransactionBuilder
|
import net.corda.core.transactions.TransactionBuilder
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
@ -71,6 +72,12 @@ interface ServicesForResolution {
|
|||||||
*/
|
*/
|
||||||
@Throws(TransactionResolutionException::class, AttachmentResolutionException::class)
|
@Throws(TransactionResolutionException::class, AttachmentResolutionException::class)
|
||||||
fun loadContractAttachment(stateRef: StateRef): Attachment
|
fun loadContractAttachment(stateRef: StateRef): Attachment
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a callback for the Node to customise the [LedgerTransaction].
|
||||||
|
*/
|
||||||
|
@JvmDefault
|
||||||
|
fun specialise(ltx: LedgerTransaction): LedgerTransaction = ltx
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,8 +70,8 @@ open class TransactionBuilder(
|
|||||||
private fun defaultLockId() = (Strand.currentStrand() as? FlowStateMachine<*>)?.id?.uuid ?: UUID.randomUUID()
|
private fun defaultLockId() = (Strand.currentStrand() as? FlowStateMachine<*>)?.id?.uuid ?: UUID.randomUUID()
|
||||||
private val log = contextLogger()
|
private val log = contextLogger()
|
||||||
|
|
||||||
private val ID_PATTERN = "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*"
|
private const val ID_PATTERN = "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*"
|
||||||
private val FQCP = Pattern.compile("$ID_PATTERN(/$ID_PATTERN)+")
|
private val FQCP: Pattern = Pattern.compile("$ID_PATTERN(/$ID_PATTERN)+")
|
||||||
private fun isValidJavaClass(identifier: String) = FQCP.matcher(identifier).matches()
|
private fun isValidJavaClass(identifier: String) = FQCP.matcher(identifier).matches()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,8 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
|
|||||||
@Throws(AttachmentResolutionException::class, TransactionResolutionException::class)
|
@Throws(AttachmentResolutionException::class, TransactionResolutionException::class)
|
||||||
@DeleteForDJVM
|
@DeleteForDJVM
|
||||||
fun toLedgerTransaction(services: ServicesForResolution): LedgerTransaction {
|
fun toLedgerTransaction(services: ServicesForResolution): LedgerTransaction {
|
||||||
return toLedgerTransactionInternal(
|
return services.specialise(
|
||||||
|
toLedgerTransactionInternal(
|
||||||
resolveIdentity = { services.identityService.partyFromKey(it) },
|
resolveIdentity = { services.identityService.partyFromKey(it) },
|
||||||
resolveAttachment = { services.attachments.openAttachment(it) },
|
resolveAttachment = { services.attachments.openAttachment(it) },
|
||||||
resolveStateRefAsSerialized = { resolveStateRefBinaryComponent(it, services) },
|
resolveStateRefAsSerialized = { resolveStateRefBinaryComponent(it, services) },
|
||||||
@ -110,6 +111,7 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
|
|||||||
// `as?` is used due to [MockServices] not implementing [ServiceHubCoreInternal]
|
// `as?` is used due to [MockServices] not implementing [ServiceHubCoreInternal]
|
||||||
isAttachmentTrusted = { (services as? ServiceHubCoreInternal)?.attachmentTrustCalculator?.calculate(it) ?: true }
|
isAttachmentTrusted = { (services as? ServiceHubCoreInternal)?.attachmentTrustCalculator?.calculate(it) ?: true }
|
||||||
)
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for deprecated toLedgerTransaction
|
// Helper for deprecated toLedgerTransaction
|
||||||
@ -129,7 +131,7 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
|
|||||||
* @throws AttachmentResolutionException if a required attachment was not found using [resolveAttachment].
|
* @throws AttachmentResolutionException if a required attachment was not found using [resolveAttachment].
|
||||||
* @throws TransactionResolutionException if an input was not found not using [resolveStateRef].
|
* @throws TransactionResolutionException if an input was not found not using [resolveStateRef].
|
||||||
*/
|
*/
|
||||||
@Deprecated("Use toLedgerTransaction(ServicesForTransaction) instead")
|
@Deprecated("Use toLedgerTransaction(ServicesForResolution) instead")
|
||||||
@Throws(AttachmentResolutionException::class, TransactionResolutionException::class)
|
@Throws(AttachmentResolutionException::class, TransactionResolutionException::class)
|
||||||
fun toLedgerTransaction(
|
fun toLedgerTransaction(
|
||||||
resolveIdentity: (PublicKey) -> Party?,
|
resolveIdentity: (PublicKey) -> Party?,
|
||||||
|
@ -10,6 +10,7 @@ import net.corda.core.node.services.IdentityService
|
|||||||
import net.corda.core.node.services.NetworkParametersService
|
import net.corda.core.node.services.NetworkParametersService
|
||||||
import net.corda.core.node.services.TransactionStorage
|
import net.corda.core.node.services.TransactionStorage
|
||||||
import net.corda.core.transactions.ContractUpgradeWireTransaction
|
import net.corda.core.transactions.ContractUpgradeWireTransaction
|
||||||
|
import net.corda.core.transactions.LedgerTransaction
|
||||||
import net.corda.core.transactions.NotaryChangeWireTransaction
|
import net.corda.core.transactions.NotaryChangeWireTransaction
|
||||||
import net.corda.core.transactions.WireTransaction
|
import net.corda.core.transactions.WireTransaction
|
||||||
import net.corda.core.transactions.WireTransaction.Companion.resolveStateRefBinaryComponent
|
import net.corda.core.transactions.WireTransaction.Companion.resolveStateRefBinaryComponent
|
||||||
@ -35,7 +36,7 @@ data class ServicesForResolutionImpl(
|
|||||||
return stateRefs.groupBy { it.txhash }.flatMap {
|
return stateRefs.groupBy { it.txhash }.flatMap {
|
||||||
val stx = validatedTransactions.getTransaction(it.key) ?: throw TransactionResolutionException(it.key)
|
val stx = validatedTransactions.getTransaction(it.key) ?: throw TransactionResolutionException(it.key)
|
||||||
val baseTx = stx.resolveBaseTransaction(this)
|
val baseTx = stx.resolveBaseTransaction(this)
|
||||||
it.value.map { StateAndRef(baseTx.outputs[it.index], it) }
|
it.value.map { ref -> StateAndRef(baseTx.outputs[ref.index], ref) }
|
||||||
}.toSet()
|
}.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,4 +70,10 @@ data class ServicesForResolutionImpl(
|
|||||||
}
|
}
|
||||||
return inner(stateRef, null)
|
return inner(stateRef, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun specialise(ltx: LedgerTransaction): LedgerTransaction {
|
||||||
|
// Specialise the LedgerTransaction here so that
|
||||||
|
// contracts are verified inside the DJVM!
|
||||||
|
return ltx
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user