mirror of
https://github.com/corda/corda.git
synced 2024-12-28 00:38:55 +00:00
CORDA-1171: Update MySQL uniqueness provider to throw the correct exception
This commit is contained in:
parent
98ba212e00
commit
2fbb34ba38
@ -17,20 +17,19 @@ import com.zaxxer.hikari.HikariConfig
|
|||||||
import com.zaxxer.hikari.HikariDataSource
|
import com.zaxxer.hikari.HikariDataSource
|
||||||
import net.corda.core.contracts.StateRef
|
import net.corda.core.contracts.StateRef
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.crypto.sha256
|
||||||
|
import net.corda.core.flows.NotaryError
|
||||||
|
import net.corda.core.flows.NotaryInternalException
|
||||||
|
import net.corda.core.flows.StateConsumptionDetails
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.node.services.UniquenessException
|
|
||||||
import net.corda.core.node.services.UniquenessProvider
|
import net.corda.core.node.services.UniquenessProvider
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
import net.corda.core.serialization.deserialize
|
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.node.services.config.MySQLConfiguration
|
import net.corda.node.services.config.MySQLConfiguration
|
||||||
import java.security.PublicKey
|
|
||||||
import java.sql.BatchUpdateException
|
import java.sql.BatchUpdateException
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
import java.sql.SQLTransientConnectionException
|
import java.sql.SQLTransientConnectionException
|
||||||
import java.util.*
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,7 +116,7 @@ class MySQLUniquenessProvider(
|
|||||||
} catch (e: BatchUpdateException) {
|
} catch (e: BatchUpdateException) {
|
||||||
log.info("Unable to commit input states, finding conflicts, txId: $txId", e)
|
log.info("Unable to commit input states, finding conflicts, txId: $txId", e)
|
||||||
conflictCounter.inc()
|
conflictCounter.inc()
|
||||||
retryTransaction(FindConflicts(states))
|
retryTransaction(FindConflicts(txId, states))
|
||||||
} finally {
|
} finally {
|
||||||
val dt = s.stop().elapsed(TimeUnit.MILLISECONDS)
|
val dt = s.stop().elapsed(TimeUnit.MILLISECONDS)
|
||||||
commitTimer.update(dt, TimeUnit.MILLISECONDS)
|
commitTimer.update(dt, TimeUnit.MILLISECONDS)
|
||||||
@ -173,26 +172,22 @@ class MySQLUniquenessProvider(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FindConflicts(val states: List<StateRef>) : RetryableTransaction {
|
private class FindConflicts(val txId: SecureHash, val states: List<StateRef>) : RetryableTransaction {
|
||||||
override fun run(conn: Connection) {
|
override fun run(conn: Connection) {
|
||||||
val conflicts = mutableMapOf<StateRef, UniquenessProvider.ConsumingTx>()
|
val conflicts = mutableMapOf<StateRef, StateConsumptionDetails>()
|
||||||
states.forEach {
|
states.forEach {
|
||||||
val st = conn.prepareStatement(findStatement).apply {
|
val st = conn.prepareStatement(findStatement).apply {
|
||||||
setBytes(1, it.txhash.bytes)
|
setBytes(1, it.txhash.bytes)
|
||||||
setInt(2, it.index)
|
setInt(2, it.index)
|
||||||
}
|
}
|
||||||
val result = st.executeQuery()
|
val result = st.executeQuery()
|
||||||
|
|
||||||
if (result.next()) {
|
if (result.next()) {
|
||||||
val consumingTxId = SecureHash.SHA256(result.getBytes(1))
|
val consumingTxId = SecureHash.SHA256(result.getBytes(1))
|
||||||
val inputIndex = result.getInt(2)
|
conflicts[it] = StateConsumptionDetails(consumingTxId.sha256())
|
||||||
val partyName = CordaX500Name.parse(result.getString(3))
|
|
||||||
val partyKey: PublicKey = result.getBytes(4).deserialize()
|
|
||||||
conflicts[it] = UniquenessProvider.ConsumingTx(consumingTxId, inputIndex, Party(partyName, partyKey))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn.commit()
|
conn.commit()
|
||||||
if (conflicts.isNotEmpty()) throw UniquenessException(UniquenessProvider.Conflict(conflicts))
|
if (conflicts.isNotEmpty()) throw NotaryInternalException(NotaryError.Conflict(txId, conflicts))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user