mirror of
https://github.com/corda/corda.git
synced 2025-02-20 17:33:15 +00:00
* Minor formatting changes. (#3758)
* NotaryServiceFlow now takes references into account when comparing number of inputs vs maxAllowedInputs. * Added reference state support for BFTSMaRt notary. * Fixes broken BFT notary tests.
This commit is contained in:
parent
ce5f38104b
commit
b0d36b6617
@ -20,7 +20,7 @@ import net.corda.core.utilities.unwrap
|
||||
abstract class NotaryServiceFlow(val otherSideSession: FlowSession, val service: TrustedAuthorityNotaryService) : FlowLogic<Void?>() {
|
||||
companion object {
|
||||
// TODO: Determine an appropriate limit and also enforce in the network parameters and the transaction builder.
|
||||
private const val maxAllowedInputs = 10_000
|
||||
private const val maxAllowedInputsAndReferences = 10_000
|
||||
}
|
||||
|
||||
@Suspendable
|
||||
@ -44,9 +44,10 @@ abstract class NotaryServiceFlow(val otherSideSession: FlowSession, val service:
|
||||
|
||||
/** Checks whether the number of input states is too large. */
|
||||
protected fun checkInputs(inputs: List<StateRef>) {
|
||||
if (inputs.size > maxAllowedInputs) {
|
||||
if (inputs.size > maxAllowedInputsAndReferences) {
|
||||
val error = NotaryError.TransactionInvalid(
|
||||
IllegalArgumentException("A transaction cannot have more than $maxAllowedInputs inputs, received: ${inputs.size}")
|
||||
IllegalArgumentException("A transaction cannot have more than $maxAllowedInputsAndReferences " +
|
||||
"inputs or references, received: ${inputs.size}")
|
||||
)
|
||||
throw NotaryInternalException(error)
|
||||
}
|
||||
|
@ -26,7 +26,14 @@ abstract class TrustedAuthorityNotaryService : NotaryService() {
|
||||
* this method does not throw an exception when input states are present multiple times within the transaction.
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun commitInputStates(inputs: List<StateRef>, txId: SecureHash, caller: Party, requestSignature: NotarisationRequestSignature, timeWindow: TimeWindow?, references: List<StateRef> = emptyList()) {
|
||||
fun commitInputStates(
|
||||
inputs: List<StateRef>,
|
||||
txId: SecureHash,
|
||||
caller: Party,
|
||||
requestSignature: NotarisationRequestSignature,
|
||||
timeWindow: TimeWindow?,
|
||||
references: List<StateRef> = emptyList()
|
||||
) {
|
||||
try {
|
||||
uniquenessProvider.commit(inputs, txId, caller, requestSignature, timeWindow, references)
|
||||
} catch (e: NotaryInternalException) {
|
||||
|
@ -139,10 +139,11 @@ class BFTNonValidatingNotaryService(
|
||||
return try {
|
||||
val id = transaction.id
|
||||
val inputs = transaction.inputs
|
||||
val references = transaction.references
|
||||
val notary = transaction.notary
|
||||
val timeWindow = (transaction as? FilteredTransaction)?.timeWindow
|
||||
if (notary !in services.myInfo.legalIdentities) throw NotaryInternalException(NotaryError.WrongNotary)
|
||||
commitInputStates(inputs, id, callerIdentity.name, requestSignature, timeWindow)
|
||||
commitInputStates(inputs, id, callerIdentity.name, requestSignature, timeWindow, references)
|
||||
log.debug { "Inputs committed successfully, signing $id" }
|
||||
BFTSMaRt.ReplicaResponse.Signature(sign(id))
|
||||
} catch (e: NotaryInternalException) {
|
||||
|
@ -223,17 +223,35 @@ object BFTSMaRt {
|
||||
*/
|
||||
abstract fun executeCommand(command: ByteArray): ByteArray?
|
||||
|
||||
protected fun commitInputStates(states: List<StateRef>, txId: SecureHash, callerName: CordaX500Name, requestSignature: NotarisationRequestSignature, timeWindow: TimeWindow?) {
|
||||
private fun checkConflict(
|
||||
conflictingStates: LinkedHashMap<StateRef, StateConsumptionDetails>,
|
||||
states: List<StateRef>,
|
||||
type: StateConsumptionDetails.ConsumedStateType
|
||||
) {
|
||||
states.forEach { stateRef ->
|
||||
commitLog[stateRef]?.let { conflictingStates[stateRef] = StateConsumptionDetails(it.sha256(), type) }
|
||||
}
|
||||
}
|
||||
|
||||
protected fun commitInputStates(
|
||||
states: List<StateRef>,
|
||||
txId: SecureHash,
|
||||
callerName: CordaX500Name,
|
||||
requestSignature: NotarisationRequestSignature,
|
||||
timeWindow: TimeWindow?,
|
||||
references: List<StateRef> = emptyList()
|
||||
) {
|
||||
log.debug { "Attempting to commit inputs for transaction: $txId" }
|
||||
services.database.transaction {
|
||||
logRequest(txId, callerName, requestSignature)
|
||||
val conflictingStates = LinkedHashMap<StateRef, StateConsumptionDetails>()
|
||||
for (state in states) {
|
||||
commitLog[state]?.let { conflictingStates[state] = StateConsumptionDetails(it.sha256()) }
|
||||
}
|
||||
|
||||
checkConflict(conflictingStates, states, StateConsumptionDetails.ConsumedStateType.INPUT_STATE)
|
||||
checkConflict(conflictingStates, references, StateConsumptionDetails.ConsumedStateType.REFERENCE_INPUT_STATE)
|
||||
|
||||
if (conflictingStates.isNotEmpty()) {
|
||||
if (!isConsumedByTheSameTx(txId.sha256(), conflictingStates)) {
|
||||
log.debug { "Failure, input states already committed: ${conflictingStates.keys}" }
|
||||
log.debug { "Failure, input states or references already committed: ${conflictingStates.keys}" }
|
||||
throw NotaryInternalException(NotaryError.Conflict(txId, conflictingStates))
|
||||
}
|
||||
} else {
|
||||
|
@ -24,7 +24,7 @@ class NonValidatingNotaryFlow(otherSideSession: FlowSession, service: TrustedAut
|
||||
@Suspendable
|
||||
override fun validateRequest(requestPayload: NotarisationPayload): TransactionParts {
|
||||
val transaction = requestPayload.coreTransaction
|
||||
checkInputs(transaction.inputs)
|
||||
checkInputs(transaction.inputs + transaction.references)
|
||||
val request = NotarisationRequest(transaction.inputs, transaction.id)
|
||||
validateRequestSignature(request, requestPayload.requestSignature)
|
||||
val parts = extractParts(transaction)
|
||||
|
@ -31,7 +31,7 @@ class ValidatingNotaryFlow(otherSideSession: FlowSession, service: TrustedAuthor
|
||||
override fun validateRequest(requestPayload: NotarisationPayload): TransactionParts {
|
||||
try {
|
||||
val stx = requestPayload.signedTransaction
|
||||
checkInputs(stx.inputs)
|
||||
checkInputs(stx.inputs + stx.references)
|
||||
validateRequestSignature(NotarisationRequest(stx.inputs, stx.id), requestPayload.requestSignature)
|
||||
val notary = stx.notary
|
||||
checkNotary(notary)
|
||||
|
Loading…
x
Reference in New Issue
Block a user