mirror of
https://github.com/corda/corda.git
synced 2025-04-07 11:27:01 +00:00
Adding createSignature(filteredTransaction) to serviceHub (#1380)
This commit is contained in:
parent
485c2feb83
commit
62c64ace23
@ -7,6 +7,7 @@ import net.corda.core.crypto.SignatureMetadata
|
||||
import net.corda.core.crypto.TransactionSignature
|
||||
import net.corda.core.node.services.*
|
||||
import net.corda.core.serialization.SerializeAsToken
|
||||
import net.corda.core.transactions.FilteredTransaction
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import java.security.PublicKey
|
||||
@ -171,7 +172,7 @@ interface ServiceHub : ServicesForResolution {
|
||||
|
||||
/**
|
||||
* Helper method to construct an initial partially signed transaction from a TransactionBuilder
|
||||
* using the default identity key contained in the node. The legal Indentity key is used to sign.
|
||||
* using the default identity key contained in the node. The legal identity key is used to sign.
|
||||
* @param builder The TransactionBuilder to seal with the node's signature.
|
||||
* Any existing signatures on the builder will be preserved.
|
||||
* @return Returns a SignedTransaction with the new node signature attached.
|
||||
@ -203,7 +204,9 @@ interface ServiceHub : ServicesForResolution {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to create an additional signature for an existing (partially) [SignedTransaction].
|
||||
* Helper method to create an additional signature for an existing (partially) [SignedTransaction]. Additional
|
||||
* [SignatureMetadata], including the
|
||||
* platform version used during signing and the cryptographic signature scheme use, is added to the signature.
|
||||
* @param signedTransaction The [SignedTransaction] to which the signature will apply.
|
||||
* @param publicKey The [PublicKey] matching to a signing [java.security.PrivateKey] hosted in the node.
|
||||
* If the [PublicKey] is actually a [net.corda.core.crypto.CompositeKey] the first leaf key found locally will be used
|
||||
@ -214,10 +217,12 @@ interface ServiceHub : ServicesForResolution {
|
||||
createSignature(signedTransaction, publicKey, SignatureMetadata(myInfo.platformVersion, Crypto.findSignatureScheme(publicKey).schemeNumberID))
|
||||
|
||||
/**
|
||||
* Helper method to create an additional signature for an existing (partially) [SignedTransaction]
|
||||
* using the default identity signing key of the node. The legal identity key is used to sign.
|
||||
* Helper method to create a signature for an existing (partially) [SignedTransaction]
|
||||
* using the default identity signing key of the node. The legal identity key is used to sign. Additional
|
||||
* [SignatureMetadata], including the
|
||||
* platform version used during signing and the cryptographic signature scheme use, is added to the signature.
|
||||
* @param signedTransaction The SignedTransaction to which the signature will apply.
|
||||
* @return The DigitalSignature.WithKey generated by signing with the internally held identity PrivateKey.
|
||||
* @return the TransactionSignature generated by signing with the internally held identity PrivateKey.
|
||||
*/
|
||||
fun createSignature(signedTransaction: SignedTransaction): TransactionSignature {
|
||||
return createSignature(signedTransaction, legalIdentityKey)
|
||||
@ -243,6 +248,36 @@ interface ServiceHub : ServicesForResolution {
|
||||
*/
|
||||
fun addSignature(signedTransaction: SignedTransaction): SignedTransaction = addSignature(signedTransaction, legalIdentityKey)
|
||||
|
||||
// Helper method to create a signature for a FilteredTransaction.
|
||||
private fun createSignature(filteredTransaction: FilteredTransaction, publicKey: PublicKey, signatureMetadata: SignatureMetadata): TransactionSignature {
|
||||
val signableData = SignableData(filteredTransaction.id, signatureMetadata)
|
||||
return keyManagementService.sign(signableData, publicKey)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to create a signature for a FilteredTransaction. Additional [SignatureMetadata], including the
|
||||
* platform version used during signing and the cryptographic signature scheme use, is added to the signature.
|
||||
* @param filteredTransaction the [FilteredTransaction] to which the signature will apply.
|
||||
* @param publicKey The [PublicKey] matching to a signing [java.security.PrivateKey] hosted in the node.
|
||||
* If the [PublicKey] is actually a [net.corda.core.crypto.CompositeKey] the first leaf key found locally will be used
|
||||
* for signing.
|
||||
* @return The [TransactionSignature] generated by signing with the internally held [java.security.PrivateKey].
|
||||
*/
|
||||
fun createSignature(filteredTransaction: FilteredTransaction, publicKey: PublicKey) =
|
||||
createSignature(filteredTransaction, publicKey, SignatureMetadata(myInfo.platformVersion, Crypto.findSignatureScheme(publicKey).schemeNumberID))
|
||||
|
||||
/**
|
||||
* Helper method to create a signature for a FilteredTransaction
|
||||
* using the default identity signing key of the node. The legal identity key is used to sign. Additional
|
||||
* [SignatureMetadata], including the platform version used during signing and the cryptographic signature scheme use,
|
||||
* is added to the signature.
|
||||
* @param filteredTransaction the FilteredTransaction to which the signature will apply.
|
||||
* @return the [TransactionSignature] generated by signing with the internally held identity [java.security.PrivateKey].
|
||||
*/
|
||||
fun createSignature(filteredTransaction: FilteredTransaction): TransactionSignature {
|
||||
return createSignature(filteredTransaction, legalIdentityKey)
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes a JDBC connection (session) object using the currently configured database.
|
||||
* Applications can use this to execute arbitrary SQL queries (native, direct, prepared, callable)
|
||||
|
@ -139,13 +139,13 @@ class FilteredLeaves(
|
||||
|
||||
/**
|
||||
* Class representing merkleized filtered transaction.
|
||||
* @param rootHash Merkle tree root hash.
|
||||
* @param id Merkle tree root hash.
|
||||
* @param filteredLeaves Leaves included in a filtered transaction.
|
||||
* @param partialMerkleTree Merkle branch needed to verify filteredLeaves.
|
||||
*/
|
||||
@CordaSerializable
|
||||
class FilteredTransaction private constructor(
|
||||
val rootHash: SecureHash,
|
||||
val id: SecureHash,
|
||||
val filteredLeaves: FilteredLeaves,
|
||||
val partialMerkleTree: PartialMerkleTree
|
||||
) {
|
||||
@ -230,13 +230,13 @@ class FilteredTransaction private constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs verification of Partial Merkle Branch against [rootHash].
|
||||
* Runs verification of Partial Merkle Branch against [id].
|
||||
*/
|
||||
@Throws(MerkleTreeException::class)
|
||||
fun verify(): Boolean {
|
||||
val hashes: List<SecureHash> = filteredLeaves.availableComponentHashes
|
||||
if (hashes.isEmpty())
|
||||
throw MerkleTreeException("Transaction without included leaves.")
|
||||
return partialMerkleTree.verify(rootHash, hashes)
|
||||
return partialMerkleTree.verify(id, hashes)
|
||||
}
|
||||
}
|
||||
|
@ -110,6 +110,10 @@ UNRELEASED
|
||||
|
||||
* ``SerializationCustomization.addToWhitelist()` now accepts multiple classes via varargs.
|
||||
|
||||
* Two functions to easily sign a ``FilteredTransaction`` have been added to ``ServiceHub``:
|
||||
``createSignature(filteredTransaction: FilteredTransaction, publicKey: PublicKey)`` and
|
||||
``createSignature(filteredTransaction: FilteredTransaction)`` to sign with the legal identity key.
|
||||
|
||||
Milestone 14
|
||||
------------
|
||||
|
||||
|
@ -45,7 +45,7 @@ In the Oracle example this step takes place in ``RatesFixFlow`` by overriding ``
|
||||
// Direct accsess to included commands, inputs, outputs, attachments etc.
|
||||
val cmds: List<Command> = ftx.filteredLeaves.commands
|
||||
val ins: List<StateRef> = ftx.filteredLeaves.inputs
|
||||
val timestamp: Timestamp? = ftx.filteredLeaves.timestamp
|
||||
val timeWindow: TimeWindow? = ftx.filteredLeaves.timeWindow
|
||||
...
|
||||
|
||||
.. literalinclude:: ../../samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt
|
||||
|
@ -85,7 +85,7 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, c
|
||||
when (response) {
|
||||
is BFTSMaRt.ClusterResponse.Error -> throw NotaryException(response.error)
|
||||
is BFTSMaRt.ClusterResponse.Signatures -> {
|
||||
log.debug("All input states of transaction ${stx.rootHash} have been committed")
|
||||
log.debug("All input states of transaction ${stx.id} have been committed")
|
||||
return response.txSignatures
|
||||
}
|
||||
}
|
||||
@ -139,16 +139,13 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, c
|
||||
|
||||
fun verifyAndCommitTx(ftx: FilteredTransaction, callerIdentity: Party): BFTSMaRt.ReplicaResponse {
|
||||
return try {
|
||||
val id = ftx.rootHash
|
||||
val id = ftx.id
|
||||
val inputs = ftx.filteredLeaves.inputs
|
||||
|
||||
validateTimeWindow(ftx.filteredLeaves.timeWindow)
|
||||
commitInputStates(inputs, id, callerIdentity)
|
||||
|
||||
log.debug { "Inputs committed successfully, signing $id" }
|
||||
val signableData = SignableData(id, SignatureMetadata(services.myInfo.platformVersion, Crypto.findSignatureScheme(services.notaryIdentityKey).schemeNumberID))
|
||||
val sig = sign(signableData)
|
||||
BFTSMaRt.ReplicaResponse.Signature(sig)
|
||||
BFTSMaRt.ReplicaResponse.Signature(sign(ftx))
|
||||
} catch (e: NotaryException) {
|
||||
log.debug { "Error processing transaction: ${e.error}" }
|
||||
BFTSMaRt.ReplicaResponse.Error(e.error)
|
||||
|
@ -251,8 +251,8 @@ object BFTSMaRt {
|
||||
return services.database.transaction { services.keyManagementService.sign(bytes, services.notaryIdentityKey) }
|
||||
}
|
||||
|
||||
protected fun sign(signableData: SignableData): TransactionSignature {
|
||||
return services.database.transaction { services.keyManagementService.sign(signableData, services.notaryIdentityKey) }
|
||||
protected fun sign(filteredTransaction: FilteredTransaction): TransactionSignature {
|
||||
return services.database.transaction { services.createSignature(filteredTransaction, services.notaryIdentityKey) }
|
||||
}
|
||||
|
||||
// TODO:
|
||||
|
@ -24,7 +24,7 @@ class NonValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryS
|
||||
when (it) {
|
||||
is FilteredTransaction -> {
|
||||
it.verify()
|
||||
TransactionParts(it.rootHash, it.filteredLeaves.inputs, it.filteredLeaves.timeWindow)
|
||||
TransactionParts(it.id, it.filteredLeaves.inputs, it.filteredLeaves.timeWindow)
|
||||
}
|
||||
is NotaryChangeWireTransaction -> TransactionParts(it.id, it.inputs, null)
|
||||
else -> {
|
||||
|
@ -175,9 +175,7 @@ object NodeInterestRates {
|
||||
// Note that we will happily sign an invalid transaction, as we are only being presented with a filtered
|
||||
// version so we can't resolve or check it ourselves. However, that doesn't matter much, as if we sign
|
||||
// an invalid transaction the signature is worthless.
|
||||
val signableData = SignableData(ftx.rootHash, SignatureMetadata(services.myInfo.platformVersion, Crypto.findSignatureScheme(signingKey).schemeNumberID))
|
||||
val signature = services.keyManagementService.sign(signableData, signingKey)
|
||||
return TransactionSignature(signature.bytes, signingKey, signableData.signatureMetadata)
|
||||
return services.createSignature(ftx, signingKey)
|
||||
}
|
||||
// DOCEND 1
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user