ENT-9923 Ledger Recovery: split out recovery metadata into own database schema. (#7364)

This commit is contained in:
Jose Coll
2023-05-24 09:42:09 +01:00
committed by GitHub
parent c7e21b3a65
commit 2e29e36e01
22 changed files with 1077 additions and 164 deletions

View File

@ -227,7 +227,7 @@ class FinalityFlow private constructor(val transaction: SignedTransaction,
else {
if (newPlatformSessions.isNotEmpty())
finaliseLocallyAndBroadcast(newPlatformSessions, transaction,
FlowTransactionMetadata(
TransactionMetadata(
serviceHub.myInfo.legalIdentities.first().name,
statesToRecord,
sessions.map { it.counterparty.name }.toSet()))
@ -258,7 +258,7 @@ class FinalityFlow private constructor(val transaction: SignedTransaction,
}
@Suspendable
private fun finaliseLocallyAndBroadcast(sessions: Collection<FlowSession>, tx: SignedTransaction, metadata: FlowTransactionMetadata) {
private fun finaliseLocallyAndBroadcast(sessions: Collection<FlowSession>, tx: SignedTransaction, metadata: TransactionMetadata) {
serviceHub.telemetryServiceInternal.span("${this::class.java.name}#finaliseLocallyAndBroadcast", flowLogic = this) {
finaliseLocally(tx, metadata = metadata)
progressTracker.currentStep = BROADCASTING
@ -310,7 +310,7 @@ class FinalityFlow private constructor(val transaction: SignedTransaction,
@Suspendable
private fun finaliseLocally(stx: SignedTransaction, notarySignatures: List<TransactionSignature> = emptyList(),
metadata: FlowTransactionMetadata? = null) {
metadata: TransactionMetadata? = null) {
progressTracker.currentStep = FINALISING_TRANSACTION
serviceHub.telemetryServiceInternal.span("${this::class.java.name}#finaliseLocally", flowLogic = this) {
if (notarySignatures.isEmpty()) {
@ -405,7 +405,7 @@ class FinalityFlow private constructor(val transaction: SignedTransaction,
progressTracker.currentStep = RECORD_UNNOTARISED
serviceHub.telemetryServiceInternal.span("${this::class.java.name}#recordUnnotarisedTransaction", flowLogic = this) {
(serviceHub as ServiceHubCoreInternal).recordUnnotarisedTransaction(tx,
FlowTransactionMetadata(
TransactionMetadata(
serviceHub.myInfo.legalIdentities.first().name,
statesToRecord,
sessions.map { it.counterparty.name }.toSet()))
@ -496,7 +496,7 @@ class ReceiveFinalityFlow @JvmOverloads constructor(private val otherSideSession
serviceHub.telemetryServiceInternal.span("${this::class.java.name}#recordUnnotarisedTransaction", flowLogic = this) {
logger.debug { "Peer recording transaction without notary signature." }
(serviceHub as ServiceHubCoreInternal).recordUnnotarisedTransaction(stx,
FlowTransactionMetadata(otherSideSession.counterparty.name, statesToRecord))
TransactionMetadata(otherSideSession.counterparty.name, statesToRecord))
}
otherSideSession.send(FetchDataFlow.Request.End) // Finish fetching data (deferredAck)
logger.info("Peer recorded transaction without notary signature. Waiting to receive notary signature.")
@ -523,7 +523,7 @@ class ReceiveFinalityFlow @JvmOverloads constructor(private val otherSideSession
} else {
serviceHub.telemetryServiceInternal.span("${this::class.java.name}#finalizeTransaction", flowLogic = this) {
(serviceHub as ServiceHubCoreInternal).finalizeTransaction(stx, statesToRecord,
FlowTransactionMetadata(otherSideSession.counterparty.name, statesToRecord))
TransactionMetadata(otherSideSession.counterparty.name, statesToRecord))
logger.info("Peer recorded transaction with recovery metadata.")
}
otherSideSession.send(FetchDataFlow.Request.End) // Finish fetching data (deferredAck)

View File

@ -10,20 +10,19 @@ import java.time.Instant
*/
@CordaSerializable
data class FlowTransaction(
data class FlowTransactionInfo(
val stateMachineRunId: StateMachineRunId,
val txId: String,
val status: TransactionStatus,
val signatures: ByteArray?,
val timestamp: Instant,
val metadata: FlowTransactionMetadata?) {
val metadata: TransactionMetadata?
) {
fun isInitiator(myCordaX500Name: CordaX500Name) =
this.metadata?.initiator == myCordaX500Name
this.metadata?.initiator == myCordaX500Name
}
@CordaSerializable
data class FlowTransactionMetadata(
data class TransactionMetadata(
val initiator: CordaX500Name,
val statesToRecord: StatesToRecord? = StatesToRecord.ONLY_RELEVANT,
val peers: Set<CordaX500Name>? = null
@ -34,4 +33,31 @@ enum class TransactionStatus {
UNVERIFIED,
VERIFIED,
IN_FLIGHT;
}
@CordaSerializable
data class RecoveryTimeWindow(val fromTime: Instant, val untilTime: Instant = Instant.now()) {
init {
if (untilTime < fromTime) {
throw IllegalArgumentException("$fromTime must be before $untilTime")
}
}
companion object {
@JvmStatic
fun between(fromTime: Instant, untilTime: Instant): RecoveryTimeWindow {
return RecoveryTimeWindow(fromTime, untilTime)
}
@JvmStatic
fun fromOnly(fromTime: Instant): RecoveryTimeWindow {
return RecoveryTimeWindow(fromTime = fromTime)
}
@JvmStatic
fun untilOnly(untilTime: Instant): RecoveryTimeWindow {
return RecoveryTimeWindow(fromTime = Instant.EPOCH, untilTime = untilTime)
}
}
}

View File

@ -4,7 +4,7 @@ import co.paralleluniverse.fibers.Suspendable
import net.corda.core.DeleteForDJVM
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.TransactionSignature
import net.corda.core.flows.FlowTransactionMetadata
import net.corda.core.flows.TransactionMetadata
import net.corda.core.internal.notary.NotaryService
import net.corda.core.node.ServiceHub
import net.corda.core.node.StatesToRecord
@ -37,7 +37,7 @@ interface ServiceHubCoreInternal : ServiceHub {
* @param txn The transaction to record.
* @param metadata Finality flow recovery metadata.
*/
fun recordUnnotarisedTransaction(txn: SignedTransaction, metadata: FlowTransactionMetadata)
fun recordUnnotarisedTransaction(txn: SignedTransaction, metadata: TransactionMetadata)
/**
* Removes transaction from data store.
@ -63,7 +63,7 @@ interface ServiceHubCoreInternal : ServiceHub {
* @param statesToRecord how the vault should treat the output states of the transaction.
* @param metadata Finality flow recovery metadata.
*/
fun finalizeTransaction(txn: SignedTransaction, statesToRecord: StatesToRecord, metadata: FlowTransactionMetadata)
fun finalizeTransaction(txn: SignedTransaction, statesToRecord: StatesToRecord, metadata: TransactionMetadata)
}
interface TransactionsResolver {