From be433c1fd092f34b3323eb59685ab945f0b59c53 Mon Sep 17 00:00:00 2001
From: Jose Coll <jose.coll@r3.com>
Date: Tue, 24 Oct 2023 17:01:37 +0100
Subject: [PATCH 1/4] ENT-10100 Filter out UNVERIFIED txns + move
 TransactionStatus package. (#7543)

---
 .ci/api-current.txt                           | 192 +-----------------
 .../coretests/flows/FinalityFlowTests.kt      |   2 +-
 .../net/corda/core/flows/RecoveryTypes.kt     |  11 +-
 .../corda/core/flows/SendTransactionFlow.kt   |   3 +
 .../net/corda/core/internal/FetchDataFlow.kt  |   5 +-
 .../core/node/services/TransactionStorage.kt  |   8 +-
 .../node/services/DbTransactionsResolver.kt   |   2 +-
 .../persistence/DBTransactionStorage.kt       |   8 +-
 .../node/internal/MockTransactionStorage.kt   |   2 +-
 9 files changed, 29 insertions(+), 204 deletions(-)

diff --git a/.ci/api-current.txt b/.ci/api-current.txt
index a7f5449ff7..79812632d4 100644
--- a/.ci/api-current.txt
+++ b/.ci/api-current.txt
@@ -1798,8 +1798,6 @@ public final class net.corda.core.crypto.Crypto extends java.lang.Object
   public static final boolean doVerify(net.corda.core.crypto.SecureHash, net.corda.core.crypto.TransactionSignature)
   public static final boolean doVerify(net.corda.core.crypto.SignatureScheme, java.security.PublicKey, byte[], byte[])
   @NotNull
-  public static final byte[] encodePublicKey(java.security.PublicKey)
-  @NotNull
   public static final java.security.Provider findProvider(String)
   @NotNull
   public static final net.corda.core.crypto.SignatureScheme findSignatureScheme(int)
@@ -2520,17 +2518,15 @@ public static final class net.corda.core.flows.ContractUpgradeFlow$Initiate exte
   protected net.corda.core.flows.AbstractStateReplacementFlow$UpgradeTx assembleTx()
 ##
 public class net.corda.core.flows.DataVendingFlow extends net.corda.core.flows.FlowLogic
-  public <init>(java.util.Set<? extends net.corda.core.flows.FlowSession>, Object, net.corda.core.flows.TransactionMetadata)
-  public <init>(java.util.Set, Object, net.corda.core.flows.TransactionMetadata, int, kotlin.jvm.internal.DefaultConstructorMarker)
   public <init>(net.corda.core.flows.FlowSession, Object)
-  public <init>(net.corda.core.flows.FlowSession, Object, net.corda.core.flows.TransactionMetadata)
-  public <init>(net.corda.core.flows.FlowSession, Object, net.corda.core.flows.TransactionMetadata, int, kotlin.jvm.internal.DefaultConstructorMarker)
   @Suspendable
   @Nullable
   public Void call()
   @NotNull
   public final java.util.Set<net.corda.core.flows.FlowSession> getOtherSessions()
   @NotNull
+  public final net.corda.core.flows.FlowSession getOtherSideSession()
+  @NotNull
   public final Object getPayload()
   @Suspendable
   @NotNull
@@ -2541,61 +2537,10 @@ public class net.corda.core.flows.DataVendingFlow extends net.corda.core.flows.F
 @DoNotImplement
 public interface net.corda.core.flows.Destination
 ##
-@CordaSerializable
-public abstract class net.corda.core.flows.DistributionList extends java.lang.Object
-  public <init>(kotlin.jvm.internal.DefaultConstructorMarker)
-##
-@CordaSerializable
-public static final class net.corda.core.flows.DistributionList$ReceiverDistributionList extends net.corda.core.flows.DistributionList
-  public <init>(byte[], net.corda.core.node.StatesToRecord)
-  @NotNull
-  public final byte[] component1()
-  @NotNull
-  public final net.corda.core.node.StatesToRecord component2()
-  @NotNull
-  public final net.corda.core.flows.DistributionList$ReceiverDistributionList copy(byte[], net.corda.core.node.StatesToRecord)
-  public boolean equals(Object)
-  @NotNull
-  public final byte[] getOpaqueData()
-  @NotNull
-  public final net.corda.core.node.StatesToRecord getReceiverStatesToRecord()
-  public int hashCode()
-  @NotNull
-  public String toString()
-##
-@CordaSerializable
-public static final class net.corda.core.flows.DistributionList$SenderDistributionList extends net.corda.core.flows.DistributionList
-  public <init>(net.corda.core.node.StatesToRecord, java.util.Map<net.corda.core.identity.CordaX500Name, ? extends net.corda.core.node.StatesToRecord>)
-  @NotNull
-  public final net.corda.core.node.StatesToRecord component1()
-  @NotNull
-  public final java.util.Map<net.corda.core.identity.CordaX500Name, net.corda.core.node.StatesToRecord> component2()
-  @NotNull
-  public final net.corda.core.flows.DistributionList$SenderDistributionList copy(net.corda.core.node.StatesToRecord, java.util.Map<net.corda.core.identity.CordaX500Name, ? extends net.corda.core.node.StatesToRecord>)
-  public boolean equals(Object)
-  @NotNull
-  public final java.util.Map<net.corda.core.identity.CordaX500Name, net.corda.core.node.StatesToRecord> getPeersToStatesToRecord()
-  @NotNull
-  public final net.corda.core.node.StatesToRecord getSenderStatesToRecord()
-  public int hashCode()
-  @NotNull
-  public String toString()
-@CordaSerializable
-public abstract class net.corda.core.flows.DistributionRecord extends java.lang.Object implements net.corda.core.contracts.NamedByHash
-  public <init>()
-  @NotNull
-  public abstract net.corda.core.crypto.SecureHash getPeerPartyId()
-  @NotNull
-  public abstract java.time.Instant getTimestamp()
-  public abstract int getTimestampDiscriminator()
-  @NotNull
-  public abstract net.corda.core.crypto.SecureHash getTxId()
-##
 @InitiatingFlow
 public final class net.corda.core.flows.FinalityFlow extends net.corda.core.flows.FlowLogic
   public <init>(net.corda.core.transactions.SignedTransaction)
   public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>)
-  public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>, java.util.Collection<? extends net.corda.core.flows.FlowSession>)
   public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>, java.util.Collection<net.corda.core.identity.Party>, net.corda.core.utilities.ProgressTracker)
   public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>, net.corda.core.node.StatesToRecord)
   public <init>(net.corda.core.transactions.SignedTransaction, java.util.Collection<? extends net.corda.core.flows.FlowSession>, net.corda.core.node.StatesToRecord, net.corda.core.utilities.ProgressTracker)
@@ -2627,32 +2572,12 @@ public static final class net.corda.core.flows.FinalityFlow$Companion$BROADCASTI
   public static final net.corda.core.flows.FinalityFlow$Companion$BROADCASTING INSTANCE
 ##
 @CordaSerializable
-public static final class net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_NOTARY_ERROR extends net.corda.core.utilities.ProgressTracker$Step
-  public static final net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_NOTARY_ERROR INSTANCE
-##
-@CordaSerializable
-public static final class net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_POST_NOTARISATION extends net.corda.core.utilities.ProgressTracker$Step
-  public static final net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_POST_NOTARISATION INSTANCE
-##
-@CordaSerializable
-public static final class net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_PRE_NOTARISATION extends net.corda.core.utilities.ProgressTracker$Step
-  public static final net.corda.core.flows.FinalityFlow$Companion$BROADCASTING_PRE_NOTARISATION INSTANCE
-##
-@CordaSerializable
-public static final class net.corda.core.flows.FinalityFlow$Companion$FINALISING_TRANSACTION extends net.corda.core.utilities.ProgressTracker$Step
-  public static final net.corda.core.flows.FinalityFlow$Companion$FINALISING_TRANSACTION INSTANCE
-##
-@CordaSerializable
 public static final class net.corda.core.flows.FinalityFlow$Companion$NOTARISING extends net.corda.core.utilities.ProgressTracker$Step
   @NotNull
   public net.corda.core.utilities.ProgressTracker childProgressTracker()
   public static final net.corda.core.flows.FinalityFlow$Companion$NOTARISING INSTANCE
 ##
 @CordaSerializable
-public static final class net.corda.core.flows.FinalityFlow$Companion$RECORD_UNNOTARISED extends net.corda.core.utilities.ProgressTracker$Step
-  public static final net.corda.core.flows.FinalityFlow$Companion$RECORD_UNNOTARISED INSTANCE
-##
-@CordaSerializable
 public class net.corda.core.flows.FlowException extends net.corda.core.CordaException implements net.corda.core.flows.IdentifiableException
   public <init>()
   public <init>(String)
@@ -2954,37 +2879,6 @@ public static final class net.corda.core.flows.FlowStackSnapshot$Frame extends j
   public String toString()
 ##
 @CordaSerializable
-public final class net.corda.core.flows.FlowTransactionInfo extends java.lang.Object
-  public <init>(net.corda.core.flows.StateMachineRunId, String, net.corda.core.flows.TransactionStatus, java.time.Instant, net.corda.core.flows.TransactionMetadata)
-  @NotNull
-  public final net.corda.core.flows.StateMachineRunId component1()
-  @NotNull
-  public final String component2()
-  @NotNull
-  public final net.corda.core.flows.TransactionStatus component3()
-  @NotNull
-  public final java.time.Instant component4()
-  @Nullable
-  public final net.corda.core.flows.TransactionMetadata component5()
-  @NotNull
-  public final net.corda.core.flows.FlowTransactionInfo copy(net.corda.core.flows.StateMachineRunId, String, net.corda.core.flows.TransactionStatus, java.time.Instant, net.corda.core.flows.TransactionMetadata)
-  public boolean equals(Object)
-  @Nullable
-  public final net.corda.core.flows.TransactionMetadata getMetadata()
-  @NotNull
-  public final net.corda.core.flows.StateMachineRunId getStateMachineRunId()
-  @NotNull
-  public final net.corda.core.flows.TransactionStatus getStatus()
-  @NotNull
-  public final java.time.Instant getTimestamp()
-  @NotNull
-  public final String getTxId()
-  public int hashCode()
-  public final boolean isInitiator(net.corda.core.identity.CordaX500Name)
-  @NotNull
-  public String toString()
-##
-@CordaSerializable
 public class net.corda.core.flows.HospitalizeFlowException extends net.corda.core.CordaRuntimeException
   public <init>()
   public <init>(String)
@@ -3246,10 +3140,6 @@ public static final class net.corda.core.flows.NotaryFlow$Client$Companion$REQUE
 public static final class net.corda.core.flows.NotaryFlow$Client$Companion$VALIDATING extends net.corda.core.utilities.ProgressTracker$Step
   public static final net.corda.core.flows.NotaryFlow$Client$Companion$VALIDATING INSTANCE
 ##
-public final class net.corda.core.flows.NotarySigCheck extends java.lang.Object
-  public final boolean needsNotarySignature(net.corda.core.transactions.SignedTransaction)
-  public static final net.corda.core.flows.NotarySigCheck INSTANCE
-##
 public final class net.corda.core.flows.ReceiveFinalityFlow extends net.corda.core.flows.FlowLogic
   public <init>(net.corda.core.flows.FlowSession)
   public <init>(net.corda.core.flows.FlowSession, net.corda.core.crypto.SecureHash)
@@ -3277,41 +3167,6 @@ public class net.corda.core.flows.ReceiveTransactionFlow extends net.corda.core.
   protected void checkBeforeRecording(net.corda.core.transactions.SignedTransaction)
 ##
 @CordaSerializable
-public final class net.corda.core.flows.RecoveryTimeWindow extends java.lang.Object
-  public <init>(java.time.Instant, java.time.Instant)
-  public <init>(java.time.Instant, java.time.Instant, int, kotlin.jvm.internal.DefaultConstructorMarker)
-  @NotNull
-  public static final net.corda.core.flows.RecoveryTimeWindow between(java.time.Instant, java.time.Instant)
-  @NotNull
-  public final java.time.Instant component1()
-  @NotNull
-  public final java.time.Instant component2()
-  @NotNull
-  public final net.corda.core.flows.RecoveryTimeWindow copy(java.time.Instant, java.time.Instant)
-  public boolean equals(Object)
-  @NotNull
-  public static final net.corda.core.flows.RecoveryTimeWindow fromOnly(java.time.Instant)
-  @NotNull
-  public final java.time.Instant getFromTime()
-  @NotNull
-  public final java.time.Instant getUntilTime()
-  public int hashCode()
-  @NotNull
-  public String toString()
-  @NotNull
-  public static final net.corda.core.flows.RecoveryTimeWindow untilOnly(java.time.Instant)
-  public static final net.corda.core.flows.RecoveryTimeWindow$Companion Companion
-##
-public static final class net.corda.core.flows.RecoveryTimeWindow$Companion extends java.lang.Object
-  public <init>(kotlin.jvm.internal.DefaultConstructorMarker)
-  @NotNull
-  public final net.corda.core.flows.RecoveryTimeWindow between(java.time.Instant, java.time.Instant)
-  @NotNull
-  public final net.corda.core.flows.RecoveryTimeWindow fromOnly(java.time.Instant)
-  @NotNull
-  public final net.corda.core.flows.RecoveryTimeWindow untilOnly(java.time.Instant)
-##
-@CordaSerializable
 public final class net.corda.core.flows.ResultSerializationException extends net.corda.core.CordaRuntimeException
   public <init>(net.corda.core.serialization.internal.MissingSerializerException)
 ##
@@ -3322,12 +3177,6 @@ public class net.corda.core.flows.SendStateAndRefFlow extends net.corda.core.flo
 ##
 public class net.corda.core.flows.SendTransactionFlow extends net.corda.core.flows.DataVendingFlow
   public <init>(net.corda.core.flows.FlowSession, net.corda.core.transactions.SignedTransaction)
-  public static final net.corda.core.flows.SendTransactionFlow$Companion Companion
-##
-public static final class net.corda.core.flows.SendTransactionFlow$Companion extends java.lang.Object
-  public <init>(kotlin.jvm.internal.DefaultConstructorMarker)
-  @NotNull
-  public final net.corda.core.identity.CordaX500Name getDUMMY_PARTICIPANT_NAME()
 ##
 public abstract class net.corda.core.flows.SignTransactionFlow extends net.corda.core.flows.FlowLogic
   public <init>(net.corda.core.flows.FlowSession)
@@ -3435,29 +3284,6 @@ public class net.corda.core.flows.StateReplacementException extends net.corda.co
   public <init>(String, Throwable, int, kotlin.jvm.internal.DefaultConstructorMarker)
 ##
 @CordaSerializable
-public final class net.corda.core.flows.TransactionMetadata extends java.lang.Object
-  public <init>(net.corda.core.identity.CordaX500Name, net.corda.core.flows.DistributionList)
-  @NotNull
-  public final net.corda.core.identity.CordaX500Name component1()
-  @NotNull
-  public final net.corda.core.flows.DistributionList component2()
-  @NotNull
-  public final net.corda.core.flows.TransactionMetadata copy(net.corda.core.identity.CordaX500Name, net.corda.core.flows.DistributionList)
-  public boolean equals(Object)
-  @NotNull
-  public final net.corda.core.flows.DistributionList getDistributionList()
-  @NotNull
-  public final net.corda.core.identity.CordaX500Name getInitiator()
-  public int hashCode()
-  @NotNull
-  public String toString()
-##
-@CordaSerializable
-public final class net.corda.core.flows.TransactionStatus extends java.lang.Enum
-  public static net.corda.core.flows.TransactionStatus valueOf(String)
-  public static net.corda.core.flows.TransactionStatus[] values()
-##
-@CordaSerializable
 public final class net.corda.core.flows.UnexpectedFlowEndException extends net.corda.core.CordaRuntimeException implements net.corda.core.flows.IdentifiableException
   public <init>(String)
   public <init>(String, Throwable)
@@ -4317,7 +4143,6 @@ public interface net.corda.core.node.ServicesForResolution
   @NotNull
   public net.corda.core.transactions.LedgerTransaction specialise(net.corda.core.transactions.LedgerTransaction)
 ##
-@CordaSerializable
 public final class net.corda.core.node.StatesToRecord extends java.lang.Enum
   public static net.corda.core.node.StatesToRecord valueOf(String)
   public static net.corda.core.node.StatesToRecord[] values()
@@ -4651,8 +4476,6 @@ public static final class net.corda.core.node.services.Vault$ConstraintInfo$Type
 @CordaSerializable
 public static final class net.corda.core.node.services.Vault$Page extends java.lang.Object
   public <init>(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends T>>, java.util.List<net.corda.core.node.services.Vault$StateMetadata>, long, net.corda.core.node.services.Vault$StateStatus, java.util.List<?>)
-  public <init>(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends T>>, java.util.List<net.corda.core.node.services.Vault$StateMetadata>, long, net.corda.core.node.services.Vault$StateStatus, java.util.List<?>, net.corda.core.contracts.StateRef)
-  public <init>(java.util.List, java.util.List, long, net.corda.core.node.services.Vault$StateStatus, java.util.List, net.corda.core.contracts.StateRef, int, kotlin.jvm.internal.DefaultConstructorMarker)
   @NotNull
   public final java.util.List<net.corda.core.contracts.StateAndRef<T>> component1()
   @NotNull
@@ -4662,17 +4485,11 @@ public static final class net.corda.core.node.services.Vault$Page extends java.l
   public final net.corda.core.node.services.Vault$StateStatus component4()
   @NotNull
   public final java.util.List<Object> component5()
-  @Nullable
-  public final net.corda.core.contracts.StateRef component6()
   @NotNull
   public final net.corda.core.node.services.Vault$Page<T> copy(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends T>>, java.util.List<net.corda.core.node.services.Vault$StateMetadata>, long, net.corda.core.node.services.Vault$StateStatus, java.util.List<?>)
-  @NotNull
-  public final net.corda.core.node.services.Vault$Page<T> copy(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends T>>, java.util.List<net.corda.core.node.services.Vault$StateMetadata>, long, net.corda.core.node.services.Vault$StateStatus, java.util.List<?>, net.corda.core.contracts.StateRef)
   public boolean equals(Object)
   @NotNull
   public final java.util.List<Object> getOtherResults()
-  @Nullable
-  public final net.corda.core.contracts.StateRef getPreviousPageAnchor()
   @NotNull
   public final net.corda.core.node.services.Vault$StateStatus getStateTypes()
   @NotNull
@@ -8233,6 +8050,8 @@ public static final class net.corda.testing.core.TestIdentity$Companion extends
   public final net.corda.testing.core.TestIdentity fresh(String, net.corda.core.crypto.SignatureScheme)
 ##
 public final class net.corda.testing.core.TestUtils extends java.lang.Object
+  @NotNull
+  public static final java.security.cert.X509CRL createCRL(net.corda.nodeapi.internal.crypto.CertificateAndKeyPair, java.util.List<? extends java.security.cert.X509Certificate>, java.net.URI, java.time.Instant, java.time.Instant, boolean, java.time.Instant, int, String)
   public static final T executeTest(java.time.Duration, kotlin.jvm.functions.Function0<kotlin.Unit>, java.time.Duration, kotlin.jvm.functions.Function0<? extends T>)
   @NotNull
   public static final net.corda.core.utilities.NetworkHostAndPort freeLocalHostAndPort()
@@ -8907,7 +8726,6 @@ public final class net.corda.testing.flows.FlowTestsUtilsKt extends java.lang.Ob
   public static final java.util.Map<net.corda.core.flows.FlowSession, net.corda.core.utilities.UntrustworthyData<Object>> receiveAll(net.corda.core.flows.FlowLogic<?>, kotlin.Pair<? extends net.corda.core.flows.FlowSession, ? extends Class<?>>, kotlin.Pair<? extends net.corda.core.flows.FlowSession, ? extends Class<?>>...)
   @NotNull
   public static final rx.Observable<T> registerCoreFlowFactory(net.corda.testing.node.internal.TestStartedNode, Class<? extends net.corda.core.flows.FlowLogic<?>>, Class<T>, kotlin.jvm.functions.Function1<? super net.corda.core.flows.FlowSession, ? extends T>, boolean)
-  public static final void waitForAllFlowsToComplete(net.corda.testing.driver.NodeHandle, int, long)
 ##
 @DoNotImplement
 public abstract class net.corda.testing.node.ClusterSpec extends java.lang.Object
@@ -9329,9 +9147,7 @@ public class net.corda.testing.node.MockServices extends java.lang.Object implem
   @NotNull
   public static final kotlin.Pair<net.corda.nodeapi.internal.persistence.CordaPersistence, net.corda.testing.node.MockServices> makeTestDatabaseAndPersistentServices(java.util.List<String>, net.corda.testing.core.TestIdentity, net.corda.core.node.NetworkParameters, java.util.Set<java.security.KeyPair>, java.util.Set<net.corda.core.identity.PartyAndCertificate>, net.corda.testing.internal.TestingNamedCacheFactory)
   public void recordTransactions(Iterable<net.corda.core.transactions.SignedTransaction>)
-  public final void recordTransactions(Iterable<net.corda.core.transactions.SignedTransaction>, boolean)
   public void recordTransactions(net.corda.core.node.StatesToRecord, Iterable<net.corda.core.transactions.SignedTransaction>)
-  public final void recordTransactions(net.corda.core.transactions.SignedTransaction, boolean)
   public void recordTransactions(net.corda.core.transactions.SignedTransaction, net.corda.core.transactions.SignedTransaction...)
   public void recordTransactions(boolean, Iterable<net.corda.core.transactions.SignedTransaction>)
   public void recordTransactions(boolean, net.corda.core.transactions.SignedTransaction, net.corda.core.transactions.SignedTransaction...)
diff --git a/core-tests/src/test/kotlin/net/corda/coretests/flows/FinalityFlowTests.kt b/core-tests/src/test/kotlin/net/corda/coretests/flows/FinalityFlowTests.kt
index 562cc3a4b4..4eb85ec26b 100644
--- a/core-tests/src/test/kotlin/net/corda/coretests/flows/FinalityFlowTests.kt
+++ b/core-tests/src/test/kotlin/net/corda/coretests/flows/FinalityFlowTests.kt
@@ -25,7 +25,6 @@ import net.corda.core.flows.ReceiverDistributionRecord
 import net.corda.core.flows.SendTransactionFlow
 import net.corda.core.flows.SenderDistributionRecord
 import net.corda.core.flows.StartableByRPC
-import net.corda.core.flows.TransactionStatus
 import net.corda.core.flows.UnexpectedFlowEndException
 import net.corda.core.identity.CordaX500Name
 import net.corda.core.identity.Party
@@ -34,6 +33,7 @@ import net.corda.core.internal.PLATFORM_VERSION
 import net.corda.core.internal.PlatformVersionSwitches
 import net.corda.core.internal.ServiceHubCoreInternal
 import net.corda.core.node.StatesToRecord
+import net.corda.core.node.services.TransactionStatus
 import net.corda.core.transactions.SignedTransaction
 import net.corda.core.transactions.TransactionBuilder
 import net.corda.core.utilities.OpaqueBytes
diff --git a/core/src/main/kotlin/net/corda/core/flows/RecoveryTypes.kt b/core/src/main/kotlin/net/corda/core/flows/RecoveryTypes.kt
index ae5d3ee4e6..b04de15187 100644
--- a/core/src/main/kotlin/net/corda/core/flows/RecoveryTypes.kt
+++ b/core/src/main/kotlin/net/corda/core/flows/RecoveryTypes.kt
@@ -1,9 +1,11 @@
 package net.corda.core.flows
 
+import net.corda.core.DoNotImplement
 import net.corda.core.contracts.NamedByHash
 import net.corda.core.crypto.SecureHash
 import net.corda.core.identity.CordaX500Name
 import net.corda.core.node.StatesToRecord
+import net.corda.core.node.services.TransactionStatus
 import net.corda.core.serialization.CordaSerializable
 import net.corda.core.utilities.OpaqueBytes
 import java.time.Instant
@@ -32,6 +34,7 @@ data class TransactionMetadata(
 )
 
 @CordaSerializable
+@DoNotImplement
 sealed class DistributionList {
 
     @CordaSerializable
@@ -47,13 +50,6 @@ sealed class DistributionList {
     ) : DistributionList()
 }
 
-@CordaSerializable
-enum class TransactionStatus {
-    UNVERIFIED,
-    VERIFIED,
-    IN_FLIGHT;
-}
-
 @CordaSerializable
 class DistributionRecords(
         val senderRecords: List<SenderDistributionRecord> = emptyList(),
@@ -63,6 +59,7 @@ class DistributionRecords(
 }
 
 @CordaSerializable
+@DoNotImplement
 abstract class DistributionRecord : NamedByHash {
     abstract val txId: SecureHash
     abstract val peerPartyId: SecureHash
diff --git a/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt b/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt
index 9f57de9580..92811e5965 100644
--- a/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt
+++ b/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt
@@ -122,6 +122,9 @@ open class DataVendingFlow(val otherSessions: Set<FlowSession>, val payload: Any
     constructor(otherSideSession: FlowSession, payload: Any, txnMetadata: TransactionMetadata? = null) : this(setOf(otherSideSession), payload, txnMetadata)
     constructor(otherSideSession: FlowSession, payload: Any) : this(otherSideSession, payload, null)
 
+    @Deprecated("Use otherSessions: Set<FlowSession>", replaceWith = ReplaceWith("otherSessions.single()"))
+    val otherSideSession: FlowSession get() = otherSessions.single()
+
     @Suspendable
     protected open fun sendPayloadAndReceiveDataRequest(otherSideSession: FlowSession, payload: Any) = otherSideSession.sendAndReceive<FetchDataFlow.Request>(payload)
 
diff --git a/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt b/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt
index 1479ab4896..44367159f6 100644
--- a/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt
+++ b/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt
@@ -13,6 +13,7 @@ import net.corda.core.internal.FetchDataFlow.DownloadedVsRequestedDataMismatch
 import net.corda.core.internal.FetchDataFlow.HashNotFound
 import net.corda.core.node.NetworkParameters
 import net.corda.core.node.services.SignedTransactionWithStatus
+import net.corda.core.node.services.TransactionStatus
 import net.corda.core.serialization.CordaSerializable
 import net.corda.core.serialization.CordaSerializationTransformEnumDefault
 import net.corda.core.serialization.CordaSerializationTransformEnumDefaults
@@ -278,7 +279,9 @@ class FetchTransactionsFlow @JvmOverloads constructor(requests: Set<SecureHash>,
 class FetchRecoverableTransactionsFlow @JvmOverloads constructor(requests: Set<SecureHash>, otherSide: FlowSession, dataType: DataType = DataType.TRANSACTION_RECOVERY) :
         FetchDataFlow<SignedTransactionWithStatus, SignedTransactionWithStatus>(requests, otherSide, dataType) {
 
-    override fun load(txid: SecureHash): SignedTransactionWithStatus? = serviceHub.validatedTransactions.getTransactionWithStatus(txid)
+    override fun load(txid: SecureHash): SignedTransactionWithStatus? = serviceHub.validatedTransactions.getTransactionWithStatus(txid)?.let {
+        if (it.status != TransactionStatus.UNVERIFIED) it else null
+    }
 }
 
 class FetchBatchTransactionsFlow(requests: Set<SecureHash>, otherSide: FlowSession) :
diff --git a/core/src/main/kotlin/net/corda/core/node/services/TransactionStorage.kt b/core/src/main/kotlin/net/corda/core/node/services/TransactionStorage.kt
index b4875040e0..a68716a6d3 100644
--- a/core/src/main/kotlin/net/corda/core/node/services/TransactionStorage.kt
+++ b/core/src/main/kotlin/net/corda/core/node/services/TransactionStorage.kt
@@ -4,7 +4,6 @@ import net.corda.core.DoNotImplement
 import net.corda.core.concurrent.CordaFuture
 import net.corda.core.contracts.NamedByHash
 import net.corda.core.crypto.SecureHash
-import net.corda.core.flows.TransactionStatus
 import net.corda.core.messaging.DataFeed
 import net.corda.core.serialization.CordaSerializable
 import net.corda.core.transactions.SignedTransaction
@@ -49,4 +48,11 @@ data class SignedTransactionWithStatus(
 ) : NamedByHash {
     override val id: SecureHash
         get() = stx.id
+}
+
+@CordaSerializable
+enum class TransactionStatus {
+    UNVERIFIED,
+    VERIFIED,
+    IN_FLIGHT;
 }
\ No newline at end of file
diff --git a/node/src/main/kotlin/net/corda/node/services/DbTransactionsResolver.kt b/node/src/main/kotlin/net/corda/node/services/DbTransactionsResolver.kt
index e82549d8e3..668b95ff92 100644
--- a/node/src/main/kotlin/net/corda/node/services/DbTransactionsResolver.kt
+++ b/node/src/main/kotlin/net/corda/node/services/DbTransactionsResolver.kt
@@ -3,12 +3,12 @@ package net.corda.node.services
 import co.paralleluniverse.fibers.Suspendable
 import net.corda.core.crypto.SecureHash
 import net.corda.core.flows.FlowLogic
-import net.corda.core.flows.TransactionStatus
 import net.corda.core.internal.FetchTransactionsFlow
 import net.corda.core.internal.ResolveTransactionsFlow
 import net.corda.core.internal.TransactionsResolver
 import net.corda.core.internal.dependencies
 import net.corda.core.node.StatesToRecord
+import net.corda.core.node.services.TransactionStatus
 import net.corda.core.transactions.SignedTransaction
 import net.corda.core.utilities.debug
 import net.corda.core.utilities.seconds
diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/DBTransactionStorage.kt b/node/src/main/kotlin/net/corda/node/services/persistence/DBTransactionStorage.kt
index 8577afe934..b66dedb22b 100644
--- a/node/src/main/kotlin/net/corda/node/services/persistence/DBTransactionStorage.kt
+++ b/node/src/main/kotlin/net/corda/node/services/persistence/DBTransactionStorage.kt
@@ -98,11 +98,11 @@ open class DBTransactionStorage(private val database: CordaPersistence, cacheFac
             return this == VERIFIED
         }
 
-        fun toTransactionStatus(): net.corda.core.flows.TransactionStatus {
+        fun toTransactionStatus(): net.corda.core.node.services.TransactionStatus {
             return when(this) {
-                UNVERIFIED -> net.corda.core.flows.TransactionStatus.UNVERIFIED
-                VERIFIED -> net.corda.core.flows.TransactionStatus.VERIFIED
-                IN_FLIGHT -> net.corda.core.flows.TransactionStatus.IN_FLIGHT
+                UNVERIFIED -> net.corda.core.node.services.TransactionStatus.UNVERIFIED
+                VERIFIED -> net.corda.core.node.services.TransactionStatus.VERIFIED
+                IN_FLIGHT -> net.corda.core.node.services.TransactionStatus.IN_FLIGHT
             }
         }
 
diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/MockTransactionStorage.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/MockTransactionStorage.kt
index d09af76ca2..ee4a4a91f5 100644
--- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/MockTransactionStorage.kt
+++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/MockTransactionStorage.kt
@@ -10,9 +10,9 @@ import net.corda.core.toFuture
 import net.corda.core.transactions.SignedTransaction
 import net.corda.node.services.api.WritableTransactionStorage
 import net.corda.core.flows.TransactionMetadata
-import net.corda.core.flows.TransactionStatus
 import net.corda.core.identity.CordaX500Name
 import net.corda.core.node.services.SignedTransactionWithStatus
+import net.corda.core.node.services.TransactionStatus
 import net.corda.testing.node.MockServices
 import rx.Observable
 import rx.subjects.PublishSubject

From be515abd0892ea3ef08db1b38881d14e9fa62d37 Mon Sep 17 00:00:00 2001
From: Jose Coll <jose.coll@r3.com>
Date: Tue, 24 Oct 2023 17:02:17 +0100
Subject: [PATCH 2/4] ENT-11004 Store Ledger Recovery records only if the
 transaction was locally stored in the first place. (#7544)

---
 .../main/kotlin/net/corda/core/flows/SendTransactionFlow.kt  | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt b/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt
index 92811e5965..93a0f59852 100644
--- a/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt
+++ b/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt
@@ -90,7 +90,7 @@ open class SendTransactionFlow(val stx: SignedTransaction,
         val DUMMY_PARTICIPANT_NAME = CordaX500Name("Transaction Participant", "London", "GB")
 
         fun makeMetaData(stx: SignedTransaction, recordMetaDataEvenIfNotFullySigned: Boolean, senderStatesToRecord: StatesToRecord, participantSessions: Set<FlowSession>, observerSessions: Set<FlowSession>): TransactionMetadata? {
-            return if (recordMetaDataEvenIfNotFullySigned || isFullySigned(stx))
+            return if (recordMetaDataEvenIfNotFullySigned || isFullySignedAndStoredLocally(stx))
                 TransactionMetadata(DUMMY_PARTICIPANT_NAME,
                         SenderDistributionList(senderStatesToRecord,
                                 (participantSessions.map { it.counterparty.name to StatesToRecord.ONLY_RELEVANT }).toMap() +
@@ -104,6 +104,9 @@ open class SendTransactionFlow(val stx: SignedTransaction,
                 stx.resolveTransactionWithSignatures(serviceHub).getMissingSigners().isEmpty()
             else false
         }
+
+        private fun isFullySignedAndStoredLocally(stx: SignedTransaction) = isFullySigned(stx)
+                && (currentTopLevel?.serviceHub?.validatedTransactions?.getTransaction(stx.id) != null)
     }
 }
 

From e52f086d1179b56bd2c505e6cff04842ade9a420 Mon Sep 17 00:00:00 2001
From: Jose Coll <jose.coll@r3.com>
Date: Thu, 26 Oct 2023 09:38:52 +0100
Subject: [PATCH 3/4] ENT-11036 Additional parameter to enable recovery of
 IN_FLIGHT transactions (post ledger peer recovery) (#7546)

---
 .../src/main/kotlin/net/corda/core/flows/LedgerRecoverFlow.kt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/core/src/main/kotlin/net/corda/core/flows/LedgerRecoverFlow.kt b/core/src/main/kotlin/net/corda/core/flows/LedgerRecoverFlow.kt
index f416fe1455..5153f98e91 100644
--- a/core/src/main/kotlin/net/corda/core/flows/LedgerRecoverFlow.kt
+++ b/core/src/main/kotlin/net/corda/core/flows/LedgerRecoverFlow.kt
@@ -37,12 +37,14 @@ data class LedgerRecoveryParameters(
     val dryRun: Boolean = false,
     val useTimeWindowNarrowing: Boolean = true,
     val verboseLogging: Boolean = false,
-    val recoveryBatchSize: Int = 1000
+    val recoveryBatchSize: Int = 1000,
+    val alsoFinalize: Boolean = false
 )
 
 @CordaSerializable
 data class LedgerRecoveryResult(
     val totalRecoveredRecords: Long,
     val totalRecoveredTransactions: Long,
+    val totalRecoveredInFlightTransactions: Long,
     val totalErrors: Long
 )

From c626d3a43562f721c9a38ab796d21930def8ab93 Mon Sep 17 00:00:00 2001
From: Rick Parker <rick.parker@r3.com>
Date: Fri, 27 Oct 2023 13:26:07 +0100
Subject: [PATCH 4/4] ENT-10100: fix batch support during recovery of in flight
 transactions (#7549)

---
 .../corda/core/flows/SendTransactionFlow.kt   |  19 +++++++++---
 .../net/corda/core/internal/FetchDataFlow.kt  |  27 +++++++-----------
 .../internal/amqp/EvolvabilityTests.kt        |  17 +++++++++++
 ...olvabilityTests.maybeSerializedTransaction | Bin 0 -> 4019 bytes
 4 files changed, 42 insertions(+), 21 deletions(-)
 create mode 100644 serialization/src/test/resources/net/corda/serialization/internal/amqp/EvolvabilityTests.maybeSerializedTransaction

diff --git a/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt b/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt
index 93a0f59852..173107dd5f 100644
--- a/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt
+++ b/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt
@@ -4,11 +4,18 @@ import co.paralleluniverse.fibers.Suspendable
 import net.corda.core.contracts.NamedByHash
 import net.corda.core.contracts.StateAndRef
 import net.corda.core.crypto.SecureHash
+import net.corda.core.flows.DistributionList.SenderDistributionList
 import net.corda.core.identity.CordaX500Name
-import net.corda.core.internal.*
+import net.corda.core.internal.FetchDataFlow
+import net.corda.core.internal.NetworkParametersStorage
+import net.corda.core.internal.PlatformVersionSwitches
+import net.corda.core.internal.RetrieveAnyTransactionPayload
+import net.corda.core.internal.ServiceHubCoreInternal
+import net.corda.core.internal.readFully
 import net.corda.core.node.ServicesForResolution
 import net.corda.core.node.StatesToRecord
 import net.corda.core.serialization.CordaSerializable
+import net.corda.core.serialization.DeprecatedConstructorForDeserialization
 import net.corda.core.serialization.SerializedBytes
 import net.corda.core.serialization.deserialize
 import net.corda.core.serialization.serialize
@@ -16,7 +23,6 @@ import net.corda.core.transactions.SignedTransaction
 import net.corda.core.utilities.trace
 import net.corda.core.utilities.unwrap
 import kotlin.collections.toSet
-import net.corda.core.flows.DistributionList.SenderDistributionList
 
 /**
  * In the words of Matt working code is more important then pretty code. This class that contains code that may
@@ -27,7 +33,12 @@ import net.corda.core.flows.DistributionList.SenderDistributionList
  */
 @CordaSerializable
 class MaybeSerializedSignedTransaction(override val id: SecureHash, val serialized: SerializedBytes<SignedTransaction>?,
-                                       val nonSerialised: SignedTransaction?) : NamedByHash {
+                                       val nonSerialised: SignedTransaction?,
+                                       val inFlight: Boolean) : NamedByHash {
+
+    @DeprecatedConstructorForDeserialization(version = 1)
+    constructor(id: SecureHash, serialized: SerializedBytes<SignedTransaction>?, nonSerialised: SignedTransaction?) : this(id, serialized, nonSerialised, false)
+
     init {
         check(serialized == null || nonSerialised == null) {
             "MaybeSerializedSignedTransaction: Serialized and non-serialized may not both be non-null."
@@ -227,7 +238,7 @@ open class DataVendingFlow(val otherSessions: Set<FlowSession>, val payload: Any
                         numSent++
                         tx
                     }
-                    FetchDataFlow.DataType.TRANSACTION_RECOVERY -> NotImplementedError("Enterprise only feature")
+                    FetchDataFlow.DataType.TRANSACTION_RECOVERY -> throw NotImplementedError("Enterprise only feature")
                     // Loop on all items returned using dataRequest.hashes.map:
                     FetchDataFlow.DataType.BATCH_TRANSACTION -> dataRequest.hashes.map { txId ->
                         if (!authorisedTransactions.isAuthorised(txId)) {
diff --git a/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt b/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt
index 44367159f6..07564bcbf4 100644
--- a/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt
+++ b/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt
@@ -12,7 +12,6 @@ import net.corda.core.flows.MaybeSerializedSignedTransaction
 import net.corda.core.internal.FetchDataFlow.DownloadedVsRequestedDataMismatch
 import net.corda.core.internal.FetchDataFlow.HashNotFound
 import net.corda.core.node.NetworkParameters
-import net.corda.core.node.services.SignedTransactionWithStatus
 import net.corda.core.node.services.TransactionStatus
 import net.corda.core.serialization.CordaSerializable
 import net.corda.core.serialization.CordaSerializationTransformEnumDefault
@@ -24,10 +23,11 @@ import net.corda.core.transactions.SignedTransaction
 import net.corda.core.utilities.NonEmptySet
 import net.corda.core.utilities.UntrustworthyData
 import net.corda.core.utilities.debug
-import net.corda.core.utilities.unwrap
 import net.corda.core.utilities.trace
+import net.corda.core.utilities.unwrap
 import java.nio.file.FileAlreadyExistsException
-import java.util.*
+import java.util.ArrayList
+import java.util.LinkedHashSet
 
 /**
  * An abstract flow for fetching typed data from a remote peer.
@@ -275,24 +275,17 @@ class FetchTransactionsFlow @JvmOverloads constructor(requests: Set<SecureHash>,
     override fun load(txid: SecureHash): SignedTransaction? = serviceHub.validatedTransactions.getTransaction(txid)
 }
 
-// Used by Enterprise Ledger Recovery
-class FetchRecoverableTransactionsFlow @JvmOverloads constructor(requests: Set<SecureHash>, otherSide: FlowSession, dataType: DataType = DataType.TRANSACTION_RECOVERY) :
-        FetchDataFlow<SignedTransactionWithStatus, SignedTransactionWithStatus>(requests, otherSide, dataType) {
-
-    override fun load(txid: SecureHash): SignedTransactionWithStatus? = serviceHub.validatedTransactions.getTransactionWithStatus(txid)?.let {
-        if (it.status != TransactionStatus.UNVERIFIED) it else null
-    }
-}
-
-class FetchBatchTransactionsFlow(requests: Set<SecureHash>, otherSide: FlowSession) :
-        FetchDataFlow<MaybeSerializedSignedTransaction, MaybeSerializedSignedTransaction>(requests, otherSide, DataType.BATCH_TRANSACTION) {
+class FetchBatchTransactionsFlow(requests: Set<SecureHash>, otherSide: FlowSession, private val recoveryMode: Boolean = false) :
+        FetchDataFlow<MaybeSerializedSignedTransaction, MaybeSerializedSignedTransaction>(requests, otherSide,
+                if (recoveryMode) DataType.TRANSACTION_RECOVERY else DataType.BATCH_TRANSACTION) {
 
     override fun load(txid: SecureHash): MaybeSerializedSignedTransaction? {
-        val tran = serviceHub.validatedTransactions.getTransaction(txid)
-        return if (tran == null) {
+        val tranAndStatus = serviceHub.validatedTransactions.getTransactionWithStatus(txid)
+        @Suppress("ComplexCondition")
+        return if (tranAndStatus == null || tranAndStatus.status == TransactionStatus.UNVERIFIED || (!recoveryMode && tranAndStatus.status == TransactionStatus.IN_FLIGHT)) {
             null
         } else {
-            MaybeSerializedSignedTransaction(txid, null, tran)
+            MaybeSerializedSignedTransaction(txid, null, tranAndStatus.stx, tranAndStatus.status == TransactionStatus.IN_FLIGHT)
         }
     }
 }
diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/EvolvabilityTests.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/EvolvabilityTests.kt
index 9514a65626..0c2ecdb8c9 100644
--- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/EvolvabilityTests.kt
+++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/EvolvabilityTests.kt
@@ -4,6 +4,7 @@ import net.corda.core.crypto.Crypto
 import net.corda.core.crypto.Crypto.generateKeyPair
 import net.corda.core.crypto.SignedData
 import net.corda.core.crypto.sign
+import net.corda.core.flows.MaybeSerializedSignedTransaction
 import net.corda.core.flows.NotarisationRequest
 import net.corda.core.identity.CordaX500Name
 import net.corda.core.identity.Party
@@ -21,6 +22,7 @@ import net.corda.serialization.internal.amqp.testutils.serialize
 import net.corda.serialization.internal.amqp.testutils.serializeAndReturnSchema
 import net.corda.serialization.internal.amqp.testutils.testDefaultFactory
 import net.corda.serialization.internal.amqp.testutils.testName
+import org.assertj.core.api.Assertions.assertThat
 import org.junit.Ignore
 import org.junit.Test
 import org.junit.jupiter.api.Assertions.assertNotSame
@@ -921,4 +923,19 @@ class EvolvabilityTests {
         assertNotSame(deserialized2.statesToConsume[0].txhash, deserialized2.statesToConsume[1].txhash)
         assertNotSame(deserialized2.statesToConsume[2].txhash, deserialized2.statesToConsume[3].txhash)
     }
+
+    @Test(timeout = 300_000)
+    fun maybeSerializedTransaction() {
+        val sf = testDefaultFactory()
+        val resource = "EvolvabilityTests.maybeSerializedTransaction"
+
+        //val A = MaybeSerializedSignedTransaction(SecureHash.randomSHA256(), null, null)
+        //File(URI("$localPath/$resource")).writeBytes(SerializationOutput(sf).serialize(A).bytes)
+
+        val url = EvolvabilityTests::class.java.getResource(resource)
+        val sc2 = url.readBytes()
+        val deserializedA = DeserializationInput(sf).deserialize(SerializedBytes<MaybeSerializedSignedTransaction>(sc2))
+
+        assertThat(deserializedA).isInstanceOf(MaybeSerializedSignedTransaction::class.java)
+    }
 }
diff --git a/serialization/src/test/resources/net/corda/serialization/internal/amqp/EvolvabilityTests.maybeSerializedTransaction b/serialization/src/test/resources/net/corda/serialization/internal/amqp/EvolvabilityTests.maybeSerializedTransaction
new file mode 100644
index 0000000000000000000000000000000000000000..8da04d34d38ad943ec2ae4a9a91db77f63b76a6c
GIT binary patch
literal 4019
zcmc&%&2Jk;6!$vbm?F`tq9{@&P!$42F*tD&J5C{yKjOrW<L{3&Mk<<JkL`8VyY|jF
z-t~zC7tSETfdfOYs0UPu3y0~U>IDh@10*EQNFXHO0=sU!wbyp)v{+m$Yv=8IzxR8;
z_uecoD`mjgY_<;{a{8~$#{6irUHL-)GiSTIC_(Jz4U1a|DV`~KVwpWY+|1R>UX&GF
zt<3f|O$^(ql~PLfX12IeIGaNJCdh~L5yS3v=F1zuCcb^+&r1*Q{q^Yn*X+XLcfkAc
zPuH&B`C0htQ|*@zgwF#36NcS@@xmFN%m3(qu9|18e#YF@AF;%1A~bM9cSV#t$ejQh
z2XjynfGBifIVV&lSk5azLV(ADECuLIhAdfL<z)#g`Z;nZK?9aUS`?s~8FP-lX`hCV
zfPu}~qp#1XgTCz~cA-peSR*Q06U*)#<l71~qD2CMV8{&Vpu0};k|axKnIKpu?^s;u
zi2F$)_eh?)ztEsR*-2hRCN1QBi?jX_FgVg-_4x~F7^3$q#^*=g84k_TkJ#x5{|`!o
z57bWbq<tD!VxiNrr~vNZpr}hQ5HYD`>EG<r%MqYE40*Q>PJvqlQq>)n8%?0Q6QPxi
zHWowy3lO;tu5z%|h7u2V%y?GyWTckj4~Mh3)$*u~?x`FTg?$4e<>t(n9P||@VL5|*
zGS3MTP&BJRbc1=hQb7=tIYGh^!mJJ}=w&ByAiW319<%ft_PO$#9YLE7DbmaVX{%c}
zY5P5L(RW*wI>R+II_<OG6u4Md1n3?6$lw@~bN)$J9SOK*^cBE*kD}=`Y*uij?A_{K
zz7gE;Z0)<a=*mhgii%p$DEkj~^CbsO^omwRgjuHB47t@)pdm5$p@6Ved;H@mGJx5{
zyJMLrf-V=Vh6Ierv8A1#z4ycV+#LvRbpF5)W9j#!Q+hhG|Gzq|Nx^8zn`*?Aq*(Wf
zv6vDqM26KjPu2P7s!W79M7^43*{xbxUsKi2>TT?)wo;{L-m{ij^&VTM*pm)ewv_W6
zQOvGscUSyMC)4o-xnjF^eCW^Aa;0cb-oH7_JRS5ceH(I`A@1u8S?Gxy87ol0nmgU*
zM1hY(ZAe5@Ou~?pT-Ap&)>nQ4Dkq{YNeIc!@wB9^hQr&+K@D%H-}MQIK^b5$$(z}3
zeM4&pe8NsnlZNLe9+IoW<mj}JYrRK;acg+Io{e>6l4})_wuw4nHNCgqc7;GRn+z2b
z)f0<|C}zh53eaWyn8z24&ld}l+~8aXLOt75HkyZP(ynSKVsI6g+3{Wjbb%RvGBID?
zvtEvFcH`}%<i6@s65g`dlC1IWv6Ct}qKg5XR%$b)z0?NsOVyRS1XHRHgtxpay%nBh
zOneR+)MvRO%b2WBDaEBT5QcuOLONle$;~-gwB*CXTKL$rnJ#sT$*eDOq*g*zOM&iB
zBy2?b=Y)!N_pqPO#x;x%TI;77msUsnMktyeTz;=P$(5!Ea79)cMW`VCDmwP^;-IfO
z$z{aXU;`%G4Gt=?-LZx&{hgiRx|`iN4SVw$Asb3Xf)!Uh<?(d$^+LL*u*E@zJ>`<f
z(m&Xl-t=cj08SKRE>M)yEe)oE8|kDg?Jx8cb1?!QOxCaY>9v%L2G_j4*(EdS!#F@M
KlFX$CjO}0SepMy_

literal 0
HcmV?d00001