Splits verifySigs into verifySigsExcept and verifyRequiredSigs to clarify usage.

This commit is contained in:
Joel Dudley 2017-07-17 15:42:08 +01:00 committed by GitHub
parent 7d1d5cc0f8
commit b37c73827f
20 changed files with 75 additions and 67 deletions

View File

@ -167,14 +167,14 @@ abstract class AbstractStateReplacementFlow {
val mySignature = sign(stx) val mySignature = sign(stx)
val swapSignatures = sendAndReceive<List<DigitalSignature.WithKey>>(otherSide, mySignature) val swapSignatures = sendAndReceive<List<DigitalSignature.WithKey>>(otherSide, mySignature)
// TODO: This step should not be necessary, as signatures are re-checked in verifySignatures. // TODO: This step should not be necessary, as signatures are re-checked in verifyRequiredSignatures.
val allSignatures = swapSignatures.unwrap { signatures -> val allSignatures = swapSignatures.unwrap { signatures ->
signatures.forEach { it.verify(stx.id) } signatures.forEach { it.verify(stx.id) }
signatures signatures
} }
val finalTx = stx + allSignatures val finalTx = stx + allSignatures
finalTx.verifySignatures() finalTx.verifyRequiredSignatures()
serviceHub.recordTransactions(finalTx) serviceHub.recordTransactions(finalTx)
} }

View File

@ -86,7 +86,7 @@ class CollectSignaturesFlow(val partiallySignedTx: SignedTransaction,
} }
// The signatures must be valid and the transaction must be valid. // The signatures must be valid and the transaction must be valid.
partiallySignedTx.verifySignatures(*notSigned.toTypedArray()) partiallySignedTx.verifySignaturesExcept(*notSigned.toTypedArray())
partiallySignedTx.tx.toLedgerTransaction(serviceHub).verify() partiallySignedTx.tx.toLedgerTransaction(serviceHub).verify()
// Determine who still needs to sign. // Determine who still needs to sign.
@ -105,7 +105,7 @@ class CollectSignaturesFlow(val partiallySignedTx: SignedTransaction,
// Verify all but the notary's signature if the transaction requires a notary, otherwise verify all signatures. // Verify all but the notary's signature if the transaction requires a notary, otherwise verify all signatures.
progressTracker.currentStep = VERIFYING progressTracker.currentStep = VERIFYING
if (notaryKey != null) stx.verifySignatures(notaryKey) else stx.verifySignatures() if (notaryKey != null) stx.verifySignaturesExcept(notaryKey) else stx.verifyRequiredSignatures()
return stx return stx
} }
@ -223,7 +223,7 @@ abstract class SignTransactionFlow(val otherParty: Party,
val signed = stx.sigs.map { it.by } val signed = stx.sigs.map { it.by }
val allSigners = stx.tx.mustSign val allSigners = stx.tx.mustSign
val notSigned = allSigners - signed val notSigned = allSigners - signed
stx.verifySignatures(*notSigned.toTypedArray()) stx.verifySignaturesExcept(*notSigned.toTypedArray())
} }
/** /**

View File

@ -159,7 +159,7 @@ open class FinalityFlow(val transactions: Iterable<SignedTransaction>,
return sorted.map { stx -> return sorted.map { stx ->
val notary = stx.tx.notary val notary = stx.tx.notary
// The notary signature(s) are allowed to be missing but no others. // The notary signature(s) are allowed to be missing but no others.
val wtx = if (notary != null) stx.verifySignatures(notary.owningKey) else stx.verifySignatures() val wtx = if (notary != null) stx.verifySignaturesExcept(notary.owningKey) else stx.verifyRequiredSignatures()
val ltx = wtx.toLedgerTransaction(augmentedLookup) val ltx = wtx.toLedgerTransaction(augmentedLookup)
ltx.verify() ltx.verify()
stx to ltx stx to ltx

View File

@ -51,7 +51,7 @@ object NotaryFlow {
"Input states must have the same Notary" "Input states must have the same Notary"
} }
try { try {
stx.verifySignatures(notaryParty.owningKey) stx.verifySignaturesExcept(notaryParty.owningKey)
} catch (ex: SignatureException) { } catch (ex: SignatureException) {
throw NotaryException(NotaryError.TransactionInvalid(ex)) throw NotaryException(NotaryError.TransactionInvalid(ex))
} }

View File

@ -119,7 +119,7 @@ class ResolveTransactionsFlow(private val txHashes: Set<SecureHash>,
// be a clearer API if we do that. But for consistency with the other c'tor we currently do not. // be a clearer API if we do that. But for consistency with the other c'tor we currently do not.
// //
// If 'stx' is set, then 'wtx' is the contents (from the c'tor). // If 'stx' is set, then 'wtx' is the contents (from the c'tor).
val wtx = stx?.verifySignatures() ?: wtx val wtx = stx?.verifyRequiredSignatures() ?: wtx
wtx?.let { wtx?.let {
fetchMissingAttachments(listOf(it)) fetchMissingAttachments(listOf(it))
val ltx = it.toLedgerTransaction(serviceHub) val ltx = it.toLedgerTransaction(serviceHub)

View File

@ -54,6 +54,17 @@ data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
class SignaturesMissingException(val missing: NonEmptySet<PublicKey>, val descriptions: List<String>, override val id: SecureHash) class SignaturesMissingException(val missing: NonEmptySet<PublicKey>, val descriptions: List<String>, override val id: SecureHash)
: NamedByHash, SignatureException("Missing signatures for $descriptions on transaction ${id.prefixChars()} for ${missing.joinToString()}") : NamedByHash, SignatureException("Missing signatures for $descriptions on transaction ${id.prefixChars()} for ${missing.joinToString()}")
/**
* Verifies the signatures on this transaction and throws if any are missing. In this context, "verifying" means
* checking they are valid signatures and that their public keys are in the contained transactions
* [BaseTransaction.mustSign] property.
*
* @throws SignatureException if any signatures are invalid or unrecognised.
* @throws SignaturesMissingException if any signatures should have been present but were not.
*/
@Throws(SignatureException::class)
fun verifyRequiredSignatures() = verifySignaturesExcept()
/** /**
* Verifies the signatures on this transaction and throws if any are missing which aren't passed as parameters. * Verifies the signatures on this transaction and throws if any are missing which aren't passed as parameters.
* In this context, "verifying" means checking they are valid signatures and that their public keys are in * In this context, "verifying" means checking they are valid signatures and that their public keys are in
@ -68,18 +79,14 @@ data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
*/ */
// DOCSTART 2 // DOCSTART 2
@Throws(SignatureException::class) @Throws(SignatureException::class)
fun verifySignatures(vararg allowedToBeMissing: PublicKey): WireTransaction { fun verifySignaturesExcept(vararg allowedToBeMissing: PublicKey): WireTransaction {
// DOCEND 2 // DOCEND 2
// Embedded WireTransaction is not deserialised until after we check the signatures. // Embedded WireTransaction is not deserialised until after we check the signatures.
checkSignaturesAreValid() checkSignaturesAreValid()
val missing = getMissingSignatures() val needed = getMissingSignatures() - allowedToBeMissing
if (missing.isNotEmpty()) {
val allowed = allowedToBeMissing.toSet()
val needed = missing - allowed
if (needed.isNotEmpty()) if (needed.isNotEmpty())
throw SignaturesMissingException(needed.toNonEmptySet(), getMissingKeyDescriptions(needed), id) throw SignaturesMissingException(needed.toNonEmptySet(), getMissingKeyDescriptions(needed), id)
}
check(tx.id == id) check(tx.id == id)
return tx return tx
} }
@ -88,7 +95,7 @@ data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
* Mathematically validates the signatures that are present on this transaction. This does not imply that * Mathematically validates the signatures that are present on this transaction. This does not imply that
* the signatures are by the right keys, or that there are sufficient signatures, just that they aren't * the signatures are by the right keys, or that there are sufficient signatures, just that they aren't
* corrupt. If you use this function directly you'll need to do the other checks yourself. Probably you * corrupt. If you use this function directly you'll need to do the other checks yourself. Probably you
* want [verifySignatures] instead. * want [verifySignaturesExcept] instead.
* *
* @throws SignatureException if a signature fails to verify. * @throws SignatureException if a signature fails to verify.
*/ */
@ -136,8 +143,8 @@ data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
operator fun plus(sigList: Collection<DigitalSignature.WithKey>) = withAdditionalSignatures(sigList) operator fun plus(sigList: Collection<DigitalSignature.WithKey>) = withAdditionalSignatures(sigList)
/** /**
* Checks the transaction's signatures are valid, optionally calls [verifySignatures] to check * Checks the transaction's signatures are valid, optionally calls [verifyRequiredSignatures] to
* all required signatures are present, and then calls [WireTransaction.toLedgerTransaction] * check all required signatures are present, and then calls [WireTransaction.toLedgerTransaction]
* with the passed in [ServiceHub] to resolve the dependencies, returning an unverified * with the passed in [ServiceHub] to resolve the dependencies, returning an unverified
* LedgerTransaction. * LedgerTransaction.
* *
@ -154,14 +161,14 @@ data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
@Throws(SignatureException::class, AttachmentResolutionException::class, TransactionResolutionException::class) @Throws(SignatureException::class, AttachmentResolutionException::class, TransactionResolutionException::class)
fun toLedgerTransaction(services: ServiceHub, checkSufficientSignatures: Boolean = true): LedgerTransaction { fun toLedgerTransaction(services: ServiceHub, checkSufficientSignatures: Boolean = true): LedgerTransaction {
checkSignaturesAreValid() checkSignaturesAreValid()
if (checkSufficientSignatures) verifySignatures() if (checkSufficientSignatures) verifyRequiredSignatures()
return tx.toLedgerTransaction(services) return tx.toLedgerTransaction(services)
} }
/** /**
* Checks the transaction's signatures are valid, optionally calls [verifySignatures] to check * Checks the transaction's signatures are valid, optionally calls [verifyRequiredSignatures]
* all required signatures are present, calls [WireTransaction.toLedgerTransaction] with the * to check all required signatures are present, calls [WireTransaction.toLedgerTransaction]
* passed in [ServiceHub] to resolve the dependencies and return an unverified * with the passed in [ServiceHub] to resolve the dependencies and return an unverified
* LedgerTransaction, then verifies the LedgerTransaction. * LedgerTransaction, then verifies the LedgerTransaction.
* *
* @throws AttachmentResolutionException if a required attachment was not found in storage. * @throws AttachmentResolutionException if a required attachment was not found in storage.
@ -173,7 +180,7 @@ data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
@Throws(SignatureException::class, AttachmentResolutionException::class, TransactionResolutionException::class, TransactionVerificationException::class) @Throws(SignatureException::class, AttachmentResolutionException::class, TransactionResolutionException::class, TransactionVerificationException::class)
fun verify(services: ServiceHub, checkSufficientSignatures: Boolean = true) { fun verify(services: ServiceHub, checkSufficientSignatures: Boolean = true) {
checkSignaturesAreValid() checkSignaturesAreValid()
if (checkSufficientSignatures) verifySignatures() if (checkSufficientSignatures) verifyRequiredSignatures()
tx.toLedgerTransaction(services).verify() tx.toLedgerTransaction(services).verify()
} }

View File

@ -46,18 +46,18 @@ class TransactionTests {
) )
assertEquals( assertEquals(
setOf(compKey, DUMMY_KEY_2.public), setOf(compKey, DUMMY_KEY_2.public),
assertFailsWith<SignedTransaction.SignaturesMissingException> { makeSigned(wtx, DUMMY_KEY_1).verifySignatures() }.missing assertFailsWith<SignedTransaction.SignaturesMissingException> { makeSigned(wtx, DUMMY_KEY_1).verifyRequiredSignatures() }.missing
) )
assertEquals( assertEquals(
setOf(compKey, DUMMY_KEY_2.public), setOf(compKey, DUMMY_KEY_2.public),
assertFailsWith<SignedTransaction.SignaturesMissingException> { makeSigned(wtx, DUMMY_KEY_1, ak).verifySignatures() }.missing assertFailsWith<SignedTransaction.SignaturesMissingException> { makeSigned(wtx, DUMMY_KEY_1, ak).verifyRequiredSignatures() }.missing
) )
makeSigned(wtx, DUMMY_KEY_1, DUMMY_KEY_2, ak, bk).verifySignatures() makeSigned(wtx, DUMMY_KEY_1, DUMMY_KEY_2, ak, bk).verifyRequiredSignatures()
makeSigned(wtx, DUMMY_KEY_1, DUMMY_KEY_2, ck).verifySignatures() makeSigned(wtx, DUMMY_KEY_1, DUMMY_KEY_2, ck).verifyRequiredSignatures()
makeSigned(wtx, DUMMY_KEY_1, DUMMY_KEY_2, ak, bk, ck).verifySignatures() makeSigned(wtx, DUMMY_KEY_1, DUMMY_KEY_2, ak, bk, ck).verifyRequiredSignatures()
makeSigned(wtx, DUMMY_KEY_1, DUMMY_KEY_2, ak).verifySignatures(compKey) makeSigned(wtx, DUMMY_KEY_1, DUMMY_KEY_2, ak).verifySignaturesExcept(compKey)
makeSigned(wtx, DUMMY_KEY_1, ak).verifySignatures(compKey, DUMMY_KEY_2.public) // Mixed allowed to be missing. makeSigned(wtx, DUMMY_KEY_1, ak).verifySignaturesExcept(compKey, DUMMY_KEY_2.public) // Mixed allowed to be missing.
} }
@Test @Test
@ -72,25 +72,25 @@ class TransactionTests {
type = TransactionType.General, type = TransactionType.General,
timeWindow = null timeWindow = null
) )
assertFailsWith<IllegalArgumentException> { makeSigned(wtx).verifySignatures() } assertFailsWith<IllegalArgumentException> { makeSigned(wtx).verifyRequiredSignatures() }
assertEquals( assertEquals(
setOf(DUMMY_KEY_1.public), setOf(DUMMY_KEY_1.public),
assertFailsWith<SignedTransaction.SignaturesMissingException> { makeSigned(wtx, DUMMY_KEY_2).verifySignatures() }.missing assertFailsWith<SignedTransaction.SignaturesMissingException> { makeSigned(wtx, DUMMY_KEY_2).verifyRequiredSignatures() }.missing
) )
assertEquals( assertEquals(
setOf(DUMMY_KEY_2.public), setOf(DUMMY_KEY_2.public),
assertFailsWith<SignedTransaction.SignaturesMissingException> { makeSigned(wtx, DUMMY_KEY_1).verifySignatures() }.missing assertFailsWith<SignedTransaction.SignaturesMissingException> { makeSigned(wtx, DUMMY_KEY_1).verifyRequiredSignatures() }.missing
) )
assertEquals( assertEquals(
setOf(DUMMY_KEY_2.public), setOf(DUMMY_KEY_2.public),
assertFailsWith<SignedTransaction.SignaturesMissingException> { makeSigned(wtx, DUMMY_CASH_ISSUER_KEY).verifySignatures(DUMMY_KEY_1.public) }.missing assertFailsWith<SignedTransaction.SignaturesMissingException> { makeSigned(wtx, DUMMY_CASH_ISSUER_KEY).verifySignaturesExcept(DUMMY_KEY_1.public) }.missing
) )
makeSigned(wtx, DUMMY_KEY_1).verifySignatures(DUMMY_KEY_2.public) makeSigned(wtx, DUMMY_KEY_1).verifySignaturesExcept(DUMMY_KEY_2.public)
makeSigned(wtx, DUMMY_KEY_2).verifySignatures(DUMMY_KEY_1.public) makeSigned(wtx, DUMMY_KEY_2).verifySignaturesExcept(DUMMY_KEY_1.public)
makeSigned(wtx, DUMMY_KEY_1, DUMMY_KEY_2).verifySignatures() makeSigned(wtx, DUMMY_KEY_1, DUMMY_KEY_2).verifyRequiredSignatures()
} }
@Test @Test

View File

@ -141,7 +141,7 @@ class CollectSignaturesFlowTests {
val flow = a.services.startFlow(TestFlowTwo.Initiator(state)) val flow = a.services.startFlow(TestFlowTwo.Initiator(state))
mockNet.runNetwork() mockNet.runNetwork()
val result = flow.resultFuture.getOrThrow() val result = flow.resultFuture.getOrThrow()
result.verifySignatures() result.verifyRequiredSignatures()
println(result.tx) println(result.tx)
println(result.sigs) println(result.sigs)
} }
@ -153,7 +153,7 @@ class CollectSignaturesFlowTests {
val flow = a.services.startFlow(CollectSignaturesFlow(ptx)) val flow = a.services.startFlow(CollectSignaturesFlow(ptx))
mockNet.runNetwork() mockNet.runNetwork()
val result = flow.resultFuture.getOrThrow() val result = flow.resultFuture.getOrThrow()
result.verifySignatures() result.verifyRequiredSignatures()
println(result.tx) println(result.tx)
println(result.sigs) println(result.sigs)
} }

View File

@ -47,7 +47,7 @@ class FinalityFlowTests {
mockNet.runNetwork() mockNet.runNetwork()
val result = flow.resultFuture.getOrThrow() val result = flow.resultFuture.getOrThrow()
val notarisedTx = result.single() val notarisedTx = result.single()
notarisedTx.verifySignatures() notarisedTx.verifyRequiredSignatures()
val transactionSeenByB = nodeB.services.database.transaction { val transactionSeenByB = nodeB.services.database.transaction {
nodeB.services.validatedTransactions.getTransaction(notarisedTx.id) nodeB.services.validatedTransactions.getTransaction(notarisedTx.id)
} }

View File

@ -50,7 +50,7 @@ class ManualFinalityFlowTests {
mockNet.runNetwork() mockNet.runNetwork()
val result = flow.resultFuture.getOrThrow() val result = flow.resultFuture.getOrThrow()
val notarisedTx = result.single() val notarisedTx = result.single()
notarisedTx.verifySignatures() notarisedTx.verifyRequiredSignatures()
// We override the participants, so node C will get a copy despite not being involved, and B won't // We override the participants, so node C will get a copy despite not being involved, and B won't
val transactionSeenByB = nodeB.services.database.transaction { val transactionSeenByB = nodeB.services.database.transaction {
nodeB.services.validatedTransactions.getTransaction(notarisedTx.id) nodeB.services.validatedTransactions.getTransaction(notarisedTx.id)

View File

@ -64,12 +64,12 @@ class TransactionSerializationTests {
val stx = notaryServices.addSignature(ptx) val stx = notaryServices.addSignature(ptx)
// Now check that the signature we just made verifies. // Now check that the signature we just made verifies.
stx.verifySignatures() stx.verifyRequiredSignatures()
// Corrupt the data and ensure the signature catches the problem. // Corrupt the data and ensure the signature catches the problem.
stx.id.bytes[5] = stx.id.bytes[5].inc() stx.id.bytes[5] = stx.id.bytes[5].inc()
assertFailsWith(SignatureException::class) { assertFailsWith(SignatureException::class) {
stx.verifySignatures() stx.verifyRequiredSignatures()
} }
} }
@ -92,7 +92,7 @@ class TransactionSerializationTests {
val dummyServices = MockServices(DUMMY_KEY_2) val dummyServices = MockServices(DUMMY_KEY_2)
val stx2 = dummyServices.addSignature(ptx2) val stx2 = dummyServices.addSignature(ptx2)
stx.copy(sigs = stx2.sigs).verifySignatures() stx.copy(sigs = stx2.sigs).verifyRequiredSignatures()
} }
} }

View File

@ -382,10 +382,11 @@ A ``SignedTransaction`` is a combination of:
:start-after: DOCSTART 1 :start-after: DOCSTART 1
:end-before: DOCEND 1 :end-before: DOCEND 1
Before adding our signature to the transaction, we'll want to verify both the transaction itself and its signatures. Before adding our signature to the transaction, we'll want to verify both the transaction's contents and the
transaction's signatures.
Verifying the transaction Verifying the transaction's contents
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To verify a transaction, we need to retrieve any states in the transaction chain that our node doesn't To verify a transaction, we need to retrieve any states in the transaction chain that our node doesn't
currently have in its local storage from the proposer(s) of the transaction. This process is handled by a built-in flow currently have in its local storage from the proposer(s) of the transaction. This process is handled by a built-in flow
called ``ResolveTransactionsFlow``. See :doc:`api-flows` for more details. called ``ResolveTransactionsFlow``. See :doc:`api-flows` for more details.
@ -460,10 +461,10 @@ the contract. Here's an example of how we might do this:
:end-before: DOCEND 34 :end-before: DOCEND 34
:dedent: 12 :dedent: 12
Verifying the signatures Verifying the transaction's signatures
^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
We also need to verify the signatures over the transaction to prevent tampering. We do this using We also need to verify that the transaction has all the required signatures, and that these signatures are valid, to
``SignedTransaction.verifySignatures``: prevent tampering. We do this using ``SignedTransaction.verifyRequiredSignatures``:
.. container:: codeset .. container:: codeset
@ -479,8 +480,8 @@ We also need to verify the signatures over the transaction to prevent tampering.
:end-before: DOCEND 35 :end-before: DOCEND 35
:dedent: 12 :dedent: 12
Optionally, we can pass ``verifySignatures`` a ``vararg`` of the public keys for which the signatures are allowed Alternatively, we can use ``SignedTransaction.verifySignaturesExcept``, which takes a ``vararg`` of the public keys for
to be missing: which the signatures are allowed to be missing:
.. container:: codeset .. container:: codeset

View File

@ -474,14 +474,14 @@ public class FlowCookbookJava {
// We can verify that a transaction has all the required // We can verify that a transaction has all the required
// signatures, and that they're all valid, by running: // signatures, and that they're all valid, by running:
// DOCSTART 35 // DOCSTART 35
fullySignedTx.verifySignatures(); fullySignedTx.verifyRequiredSignatures();
// DOCEND 35 // DOCEND 35
// If the transaction is only partially signed, we have to pass in // If the transaction is only partially signed, we have to pass in
// a list of the public keys corresponding to the missing // a list of the public keys corresponding to the missing
// signatures, explicitly telling the system not to check them. // signatures, explicitly telling the system not to check them.
// DOCSTART 36 // DOCSTART 36
onceSignedTx.verifySignatures(counterpartyPubKey); onceSignedTx.verifySignaturesExcept(counterpartyPubKey);
// DOCEND 36 // DOCEND 36
// We can also choose to only check the signatures that are // We can also choose to only check the signatures that are

View File

@ -60,7 +60,7 @@ class MyValidatingNotaryFlow(otherSide: Party, service: MyCustomValidatingNotary
private fun checkSignatures(stx: SignedTransaction) { private fun checkSignatures(stx: SignedTransaction) {
try { try {
stx.verifySignatures(serviceHub.myInfo.notaryIdentity.owningKey) stx.verifySignaturesExcept(serviceHub.myInfo.notaryIdentity.owningKey)
} catch(e: SignatureException) { } catch(e: SignatureException) {
throw NotaryException(NotaryError.TransactionInvalid(e)) throw NotaryException(NotaryError.TransactionInvalid(e))
} }

View File

@ -457,14 +457,14 @@ object FlowCookbook {
// We can verify that a transaction has all the required // We can verify that a transaction has all the required
// signatures, and that they're all valid, by running: // signatures, and that they're all valid, by running:
// DOCSTART 35 // DOCSTART 35
fullySignedTx.verifySignatures() fullySignedTx.verifyRequiredSignatures()
// DOCEND 35 // DOCEND 35
// If the transaction is only partially signed, we have to pass in // If the transaction is only partially signed, we have to pass in
// a list of the public keys corresponding to the missing // a list of the public keys corresponding to the missing
// signatures, explicitly telling the system not to check them. // signatures, explicitly telling the system not to check them.
// DOCSTART 36 // DOCSTART 36
onceSignedTx.verifySignatures(counterpartyPubKey) onceSignedTx.verifySignaturesExcept(counterpartyPubKey)
// DOCEND 36 // DOCEND 36
// We can also choose to only check the signatures that are // We can also choose to only check the signatures that are

View File

@ -159,7 +159,7 @@ class ForeignExchangeFlow(val tradeId: String,
val allPartySignedTx = sendAndReceive<DigitalSignature.WithKey>(remoteRequestWithNotary.owner, signedTransaction).unwrap { val allPartySignedTx = sendAndReceive<DigitalSignature.WithKey>(remoteRequestWithNotary.owner, signedTransaction).unwrap {
val withNewSignature = signedTransaction + it val withNewSignature = signedTransaction + it
// check all signatures are present except the notary // check all signatures are present except the notary
withNewSignature.verifySignatures(withNewSignature.tx.notary!!.owningKey) withNewSignature.verifySignaturesExcept(withNewSignature.tx.notary!!.owningKey)
// This verifies that the transaction is contract-valid, even though it is missing signatures. // This verifies that the transaction is contract-valid, even though it is missing signatures.
// In a full solution there would be states tracking the trade request which // In a full solution there would be states tracking the trade request which
@ -234,7 +234,7 @@ class ForeignExchangeRemoteFlow(val source: Party) : FlowLogic<Unit>() {
val proposedTrade = sendAndReceive<SignedTransaction>(source, ourResponse).unwrap { val proposedTrade = sendAndReceive<SignedTransaction>(source, ourResponse).unwrap {
val wtx = it.tx val wtx = it.tx
// check all signatures are present except our own and the notary // check all signatures are present except our own and the notary
it.verifySignatures(ourKey, wtx.notary!!.owningKey) it.verifySignaturesExcept(ourKey, wtx.notary!!.owningKey)
// We need to fetch their complete input states and dependencies so that verify can operate // We need to fetch their complete input states and dependencies so that verify can operate
checkDependencies(it) checkDependencies(it)

View File

@ -197,7 +197,7 @@ class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : Flow
val agreedTx = selfSignedTx + it val agreedTx = selfSignedTx + it
// Receive back their signature and confirm that it is for an unmodified transaction // Receive back their signature and confirm that it is for an unmodified transaction
// Also that the only missing signature is from teh Notary // Also that the only missing signature is from teh Notary
agreedTx.verifySignatures(notary.owningKey) agreedTx.verifySignaturesExcept(notary.owningKey)
// Recheck the data of the transaction. Note we run toLedgerTransaction on the WireTransaction // Recheck the data of the transaction. Note we run toLedgerTransaction on the WireTransaction
// as we do not have all the signature. // as we do not have all the signature.
agreedTx.tx.toLedgerTransaction(serviceHub).verify() agreedTx.tx.toLedgerTransaction(serviceHub).verify()
@ -226,7 +226,7 @@ class RecordCompletionFlow(val source: Party) : FlowLogic<Unit>() {
// First we receive the verdict transaction signed by their single key // First we receive the verdict transaction signed by their single key
val completeTx = receive<SignedTransaction>(source).unwrap { val completeTx = receive<SignedTransaction>(source).unwrap {
// Check the transaction is signed apart from our own key and the notary // Check the transaction is signed apart from our own key and the notary
val wtx = it.verifySignatures(serviceHub.myInfo.legalIdentity.owningKey, it.tx.notary!!.owningKey) val wtx = it.verifySignaturesExcept(serviceHub.myInfo.legalIdentity.owningKey, it.tx.notary!!.owningKey)
// Check the transaction data is correctly formed // Check the transaction data is correctly formed
wtx.toLedgerTransaction(serviceHub).verify() wtx.toLedgerTransaction(serviceHub).verify()
// Confirm that this is the expected type of transaction // Confirm that this is the expected type of transaction

View File

@ -270,8 +270,8 @@ apply any new signatures to its original proposal to ensure the contents
of the transaction has not been altered by the remote parties. of the transaction has not been altered by the remote parties.
The typical code therefore checks the received ``SignedTransaction`` The typical code therefore checks the received ``SignedTransaction``
using the ``verifySignatures`` method, but excluding itself, the notary using the ``verifySignaturesExcept`` method, excluding itself, the
and any other parties yet to apply their signature. The contents of the notary and any other parties yet to apply their signature. The contents of the
``WireTransaction`` inside the ``SignedTransaction`` should be fully ``WireTransaction`` inside the ``SignedTransaction`` should be fully
verified further by expanding with ``toLedgerTransaction`` and calling verified further by expanding with ``toLedgerTransaction`` and calling
``verify``. Further context specific and business checks should then be ``verify``. Further context specific and business checks should then be

View File

@ -291,7 +291,7 @@ class ObligationTests {
assertEquals(1, stx.tx.outputs.size) assertEquals(1, stx.tx.outputs.size)
assertEquals(stateAndRef.state.data.copy(lifecycle = Lifecycle.DEFAULTED), stx.tx.outputs[0].data) assertEquals(stateAndRef.state.data.copy(lifecycle = Lifecycle.DEFAULTED), stx.tx.outputs[0].data)
stx.verifySignatures() stx.verifyRequiredSignatures()
// And set it back // And set it back
stateAndRef = stx.tx.outRef<Obligation.State<Currency>>(0) stateAndRef = stx.tx.outRef<Obligation.State<Currency>>(0)
@ -302,7 +302,7 @@ class ObligationTests {
stx = notaryServices.addSignature(ptx) stx = notaryServices.addSignature(ptx)
assertEquals(1, stx.tx.outputs.size) assertEquals(1, stx.tx.outputs.size)
assertEquals(stateAndRef.state.data.copy(lifecycle = Lifecycle.NORMAL), stx.tx.outputs[0].data) assertEquals(stateAndRef.state.data.copy(lifecycle = Lifecycle.NORMAL), stx.tx.outputs[0].data)
stx.verifySignatures() stx.verifyRequiredSignatures()
} }
/** Test generating a transaction to settle an obligation. */ /** Test generating a transaction to settle an obligation. */

View File

@ -33,7 +33,7 @@ class ValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryServ
private fun checkSignatures(stx: SignedTransaction) { private fun checkSignatures(stx: SignedTransaction) {
try { try {
stx.verifySignatures(serviceHub.myInfo.notaryIdentity.owningKey) stx.verifySignaturesExcept(serviceHub.myInfo.notaryIdentity.owningKey)
} catch(e: SignatureException) { } catch(e: SignatureException) {
throw NotaryException(NotaryError.TransactionInvalid(e)) throw NotaryException(NotaryError.TransactionInvalid(e))
} }