Scorex under the hood uses Akka actor references for message passing between modules meaning there's no static type checking for class properties that use
ActorRef. What you can do then is, for example,
implicit lazy val settings = new ForgingSettings {
override val settingsJSON: Map[String, circe.Json] = settingsFromFile(settingsFilename)
}
val forger: ActorRef = actorSystem.actorOf(Props(classOf[Forger], settings, nodeViewHolderRef))
override val localInterface: ActorRef = actorSystem.actorOf(Props(classOf[BifrostLocalInterface], nodeViewHolderRef, forger, settings))
If you want to change consensus rules or whatnot, just reference different files. Alternatively, you can always do this in memory. For reference, a simple
ForgingSettings might look like this:
trait ForgingSettings extends Settings with ForgingConstants {
val InitialDifficulty = 15000000L
val MinimumDifficulty = 100L
lazy val offlineGeneration = settingsJSON.get("offlineGeneration").flatMap(_.asBoolean).getOrElse(false)
lazy val posAttachmentSize = settingsJSON.get("posAttachmentSize").flatMap(_.asNumber).flatMap(_.toInt)
.getOrElse(DefaulPtosAttachmentSize)
val DefaulPtosAttachmentSize = 1024
override def toString: String = (Map("BlockDelay" -> blockGenerationDelay.length.asJson) ++
settingsJSON.map(s => s._1 -> s._2)).asJson.spaces2
}
(This is using io.circe for json parsing) You can generally just swap between different children of
Settings for different consensus modules.
Scorex also has a testkit built in if you want to do discrete runs quickly between different settings. It would essentially be handled the same way as well.
Cheers!