forked from hyperledger-labs/splice
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbootstrap-canton.sc
More file actions
126 lines (115 loc) · 4.93 KB
/
bootstrap-canton.sc
File metadata and controls
126 lines (115 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import scala.collection.mutable.ListBuffer
import cats.syntax.either._
import cats.syntax.functorFilter._
import java.nio.file.{Paths, Files}
import java.nio.charset.StandardCharsets
import com.daml.nonempty.NonEmpty
import com.digitalasset.canton.console.{
LocalInstanceReference,
LocalMediatorReference,
LocalSequencerReference,
}
import com.digitalasset.canton.SynchronizerAlias
import com.digitalasset.canton.synchronizer.config.SynchronizerParametersConfig
import com.digitalasset.canton.protocol.DynamicSynchronizerParameters
import com.digitalasset.canton.topology.transaction.SignedTopologyTransaction.GenericSignedTopologyTransaction
import com.digitalasset.canton.topology.transaction.TopologyChangeOp
import com.digitalasset.canton.version.ProtocolVersion
println("Running canton bootstrap script...")
val tokenFile = System.getenv("CANTON_TOKEN_FILENAME")
if (tokenFile == null) {
sys.error("Environment variable CANTON_TOKEN_FILENAME was not set")
}
val domainParametersConfig = SynchronizerParametersConfig(
alphaVersionSupport = true,
// simtime does not work with non-zero topology change delay so we overwrite it matching the Canton tests
topologyChangeDelay = Some(if (tokenFile == "canton-simtime.tokens") NonNegativeFiniteDuration.Zero else NonNegativeFiniteDuration.ofMillis(250)),
)
def staticParameters(sequencer: LocalInstanceReference) =
domainParametersConfig
.toStaticSynchronizerParameters(sequencer.config.crypto, ProtocolVersion.v34, NonNegativeInt.zero)
.map(StaticSynchronizerParameters(_))
.getOrElse(sys.error("whatever"))
def bootstrapOtherDomain(
name: String,
sequencer: LocalSequencerReference,
mediator: LocalMediatorReference,
) = {
bootstrap.synchronizer(
name,
synchronizerOwners = Seq(sequencer),
sequencers = Seq(sequencer),
mediators = Seq(mediator),
synchronizerThreshold = PositiveInt.one,
staticSynchronizerParameters = staticParameters(sequencer),
)
// For some stupid reason bootstrap.domain does not allow changing the dynamic domain parameters
// so we overwrite it here.
val synchronizerId = sequencer.synchronizer_id
// Align the reconciliation interval and catchup config with what our triggers set.
// This doesn't really matter for splitwell but it matters for the soft synchronizer upgrade test.
sequencer.topology.synchronizer_parameters.propose_update(
synchronizerId,
parameters =>
parameters.update(
reconciliationInterval = PositiveDurationSeconds.ofMinutes(30),
acsCommitmentsCatchUpParameters = Some(
AcsCommitmentsCatchUpParameters(
catchUpIntervalSkip = PositiveInt.tryCreate(24),
nrIntervalsToTriggerCatchUp = PositiveInt.tryCreate(2),
)
),
preparationTimeRecordTimeTolerance = NonNegativeFiniteDuration.ofHours(24),
mediatorDeduplicationTimeout = NonNegativeFiniteDuration.ofHours(48),
),
signedBy = Some(sequencer.id.uid.namespace.fingerprint),
// This is test code so just force the change.
force = ForceFlags(ForceFlag.PreparationTimeRecordTimeToleranceIncrease),
)
}
Seq(
("splitwell", splitwellSequencer, splitwellMediator),
("splitwellUpgrade", splitwellUpgradeSequencer, splitwellUpgradeMediator),
).foreach((bootstrapOtherDomain _).tupled)
// These user allocations are only there
// for local testing. Our tests allocate their own users.
println(s"Allocating users for local testing...")
val userParticipants = ListBuffer[(String, String)]()
Seq(
(sv1Participant, "sv1"),
(sv2Participant, "sv2"),
(sv3Participant, "sv3"),
(sv4Participant, "sv4"),
(aliceParticipant, "alice_validator_user"),
(bobParticipant, "bob_validator_user"),
(splitwellParticipant, "splitwell_validator_user"),
).foreach { case (participant, user) =>
participant.ledger_api.users.create(
id = user,
primaryParty = None,
actAs = Set.empty,
readAs = Set.empty,
participantAdmin = true,
)
userParticipants.append(user -> participant.id.uid.toProtoPrimitive)
}
println(s"Writing down participant ids...")
val participantIdsContent =
userParticipants.map(x => s"${x._1} ${x._2}").mkString(System.lineSeparator())
Files.write(
Paths.get(System.getenv("CANTON_PARTICIPANTS_FILENAME")),
participantIdsContent.getBytes(StandardCharsets.UTF_8),
)
// Inserting extra commands here (do not edit this line)
println(s"Collecting admin tokens...")
val adminTokensData = ListBuffer[(String, String)]()
participants.local.foreach(participant => {
val adminToken = participant.underlying.map(_.adminTokenDispenser.getCurrentToken.secret).getOrElse("")
val port = participant.config.ledgerApi.internalPort.get.unwrap
adminTokensData.append(s"$port" -> adminToken)
})
println(s"Writing admin tokens file to $tokenFile...")
val adminTokensContent =
adminTokensData.map(x => s"${x._1} ${x._2}").mkString(System.lineSeparator())
Files.write(Paths.get(tokenFile), adminTokensContent.getBytes(StandardCharsets.UTF_8))
println("Canton bootstrap script done.")