Repository: hashgraph/hedera-services
Issue: ExpiryManager needs access to mutable schedules FCM to rebuild on reconnect

**Summary of the defect**
If Services restarts from a saved state, the `ExpiryManager` is currently injected with the **object reference** of the `schedules` FCM from this state. If the restarted node is behind, and must reconnect, this results in the schedule entity expiration queue being rebuilt from the wrong FCM.

**Suggested fix**
Inject a `Supplier` providing the mutable `schedules` FCM.

Changed files:
hedera-node/src/test/java/com/hedera/services/state/expiry/ExpiryManagerTest.java
hedera-node/src/main/java/com/hedera/services/context/ServicesContext.java
hedera-node/src/main/java/com/hedera/services/state/expiry/ExpiryManager.java

diff --git a/hedera-node/src/main/java/com/hedera/services/context/ServicesContext.java b/hedera-node/src/main/java/com/hedera/services/context/ServicesContext.java
index 11a8d42812..50d856e7e8 100644
--- a/hedera-node/src/main/java/com/hedera/services/context/ServicesContext.java
+++ b/hedera-node/src/main/java/com/hedera/services/context/ServicesContext.java
@@ -1502,7 +1502,7 @@ public class ServicesContext {
 	public ExpiryManager expiries() {
 		if (expiries == null) {
 			var histories = txnHistories();
-			expiries = new ExpiryManager(recordCache(), histories, scheduleStore(), schedules());
+			expiries = new ExpiryManager(recordCache(), histories, scheduleStore(), this::schedules);
 		}
 		return expiries;
 	}
diff --git a/hedera-node/src/main/java/com/hedera/services/state/expiry/ExpiryManager.java b/hedera-node/src/main/java/com/hedera/services/state/expiry/ExpiryManager.java
index 31e031ca01..b29157ebc3 100644
--- a/hedera-node/src/main/java/com/hedera/services/state/expiry/ExpiryManager.java
+++ b/hedera-node/src/main/java/com/hedera/services/state/expiry/ExpiryManager.java
@@ -41,11 +41,12 @@ import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 
 public class ExpiryManager {
 	private final RecordCache recordCache;
 	private final Map<TransactionID, TxnIdRecentHistory> txnHistories;
-	private final FCMap<MerkleEntityId, MerkleSchedule> schedules;
+	private final Supplier<FCMap<MerkleEntityId, MerkleSchedule>> schedules;
 
 	private final ScheduleStore scheduleStore;
 
@@ -57,7 +58,7 @@ public class ExpiryManager {
 			RecordCache recordCache,
 			Map<TransactionID, TxnIdRecentHistory> txnHistories,
 			ScheduleStore scheduleStore,
-			FCMap<MerkleEntityId, MerkleSchedule> schedules
+			Supplier<FCMap<MerkleEntityId, MerkleSchedule>> schedules
 	) {
 		this.recordCache = recordCache;
 		this.txnHistories = txnHistories;
@@ -94,7 +95,7 @@ public class ExpiryManager {
 		entityExpiries.reset();
 
 		var expiries = new ArrayList<Map.Entry<Pair<Long, Consumer<EntityId>>, Long>>();
-		schedules.forEach((id, schedule) -> {
+		schedules.get().forEach((id, schedule) -> {
 			Consumer<EntityId> consumer = scheduleStore::expire;
 			var pair = Pair.of(id.getNum(), consumer);
 			expiries.add(new AbstractMap.SimpleImmutableEntry<>(pair, schedule.expiry()));
diff --git a/hedera-node/src/test/java/com/hedera/services/state/expiry/ExpiryManagerTest.java b/hedera-node/src/test/java/com/hedera/services/state/expiry/ExpiryManagerTest.java
index 4a04cc55dd..d576d7dd40 100644
--- a/hedera-node/src/test/java/com/hedera/services/state/expiry/ExpiryManagerTest.java
+++ b/hedera-node/src/test/java/com/hedera/services/state/expiry/ExpiryManagerTest.java
@@ -102,7 +102,7 @@ class ExpiryManagerTest {
 		given(expiringEntity.getKey()).willReturn(schedule.getScheduleNum());
 		given(expiringEntity.getValue()).willReturn(entityIdConsumer);
 
-		subject = new ExpiryManager(recordCache, txnHistories, scheduleStore, schedules);
+		subject = new ExpiryManager(recordCache, txnHistories, scheduleStore, () -> schedules);
 	}
 
 	@Test
@@ -155,7 +155,7 @@ class ExpiryManagerTest {
 		txnHistories = mock(Map.class);
 
 		// given:
-		subject = new ExpiryManager(recordCache, txnHistories, scheduleStore, schedules);
+		subject = new ExpiryManager(recordCache, txnHistories, scheduleStore, () -> schedules);
 		// and:
 		subject.trackRecord(payer, oldExpiry);
 		// and: