diff --git a/src/FSLibrary/FSLibrary.fsproj b/src/FSLibrary/FSLibrary.fsproj
index b33c5785..0586d390 100644
--- a/src/FSLibrary/FSLibrary.fsproj
+++ b/src/FSLibrary/FSLibrary.fsproj
@@ -76,6 +76,7 @@
+
diff --git a/src/FSLibrary/MissionValidatorSetup.fs b/src/FSLibrary/MissionValidatorSetup.fs
new file mode 100644
index 00000000..fa106f43
--- /dev/null
+++ b/src/FSLibrary/MissionValidatorSetup.fs
@@ -0,0 +1,55 @@
+// Copyright 2019 Stellar Development Foundation and contributors. Licensed
+// under the Apache License, Version 2.0. See the COPYING file at the root
+// of this distribution or at http://www.apache.org/licenses/LICENSE-2.0
+
+module MissionValidatorSetup
+
+open StellarCoreSet
+open StellarCorePeer
+open StellarMissionContext
+open StellarSupercluster
+open StellarFormation
+open StellarStatefulSets
+open StellarCoreHTTP
+
+// This mission creates a network with validator configurations that closely
+// mirror how tier 1 validators are actually configured. It uses both Postgres
+// and has history archives enabled. This is a smoke test that spins up the
+// network, runs for ~70 ledgers with load generation, verifies history
+// publishing works, then spins it down.
+let validatorSetup (context: MissionContext) =
+ let opts =
+ { CoreSetOptions.GetDefault context.image with
+ dbType = Postgres
+ // Use disk-backed storage like production validators
+ emptyDirType = DiskBackedEmptyDir
+ localHistory = true
+ accelerateTime = true
+ // Enable maintenance like production validators
+ performMaintenance = true }
+
+ let coreSet = MakeLiveCoreSet "core" opts
+
+ let context =
+ { context with
+ numAccounts = 200
+ genesisTestAccountCount = Some(200)
+ numTxs = 500
+ txRate = 10 }
+
+ context.Execute
+ [ coreSet ]
+ None
+ (fun (formation: StellarFormation) ->
+ formation.WaitUntilSynced [ coreSet ]
+ formation.UpgradeProtocolToLatest [ coreSet ]
+
+ // Run load generation to ensure blocks aren't empty
+ formation.RunLoadgen coreSet context.GeneratePaymentLoad
+
+ // Wait for a few more ledgers to ensure publishing happens
+ let peer = formation.NetworkCfg.GetPeer coreSet 0
+ peer.WaitForFewLedgers 20
+
+ if (peer.GetMetrics().HistoryPublishSuccess.Count = 0) then
+ failwith "history.publish.success is 0, expected > 0")
diff --git a/src/FSLibrary/StellarMission.fs b/src/FSLibrary/StellarMission.fs
index 2738cb0c..677eb2f8 100644
--- a/src/FSLibrary/StellarMission.fs
+++ b/src/FSLibrary/StellarMission.fs
@@ -47,6 +47,7 @@ open MissionPubnetNetworkLimitsBench
open MissionMixedNominationLeaderElection
open MissionUpgradeSCPSettings
open MissionUpgradeTxClusters
+open MissionValidatorSetup
type Mission = (MissionContext -> unit)
@@ -95,4 +96,5 @@ let allMissions : Map =
("MixedNominationLeaderElectionWithOldMajority", mixedNominationLeaderElectionWithOldMajority)
("MixedNominationLeaderElectionWithNewMajority", mixedNominationLeaderElectionWithNewMajority)
("UpgradeSCPSettings", upgradeSCPSettings)
- ("UpgradeTxClusters", upgradeTxClusters) |]
+ ("UpgradeTxClusters", upgradeTxClusters)
+ ("ValidatorSetup", validatorSetup) |]