Skip to content

Commit 56e0123

Browse files
[ci] init
Signed-off-by: Julien Tinguely <[email protected]>
1 parent 9d1025c commit 56e0123

File tree

19 files changed

+676
-78
lines changed

19 files changed

+676
-78
lines changed

.github/workflows/build.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,20 @@ jobs:
158158
daml_base_version: ${{ inputs.daml_base_version }}
159159
secrets: inherit
160160

161+
scala_test_signatures:
162+
uses: ./.github/workflows/build.scala_test.yml
163+
with:
164+
runs_on: self-hosted-k8s-small
165+
test_names_file: 'test-full-class-names-signatures.log'
166+
start_canton_options: -B "scripts/bootstrap/bootstrap-canton-with-deprecated-keys.sc"
167+
parallelism: 1
168+
test_name: signatures
169+
with_gcp_creds: false
170+
commit_sha: ${{ inputs.commit_sha }}
171+
daml_base_version: ${{ inputs.daml_base_version }}
172+
oss_only: ${{ inputs.oss_only }}
173+
secrets: inherit
174+
161175
scala_test_wall_clock_time:
162176
uses: ./.github/workflows/build.scala_test.yml
163177
with:

TESTING.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
- [Handling Errors in Integration Tests](#handling-errors-in-integration-tests)
2424
- [Connecting external tools to the shared Canton instances](#connecting-external-tools-to-the-shared-canton-instances)
2525
- [Testing App Upgrades](#testing-app-upgrades)
26+
- [Testing from a custom canton instance]
2627
- [Deployment Tests](#deployment-tests)
2728
- [CI Without Approval](#ci-without-approval)
2829

@@ -403,6 +404,10 @@ PRs/commits that include `[breaking]` in their commit message, or that bump the
403404
The test spins up a full network in the source version, creates some activity, then gradually upgrades several of the components (SVs and validators)
404405
one-by-one to the current commit's version.
405406

407+
### Testing from a custom canton instance
408+
409+
If you need a custom canton instance to run your test, use `./start-canton.sh -B scripts/bootstrap/<your-script>`.
410+
406411
## Deployment Tests
407412

408413
Static deployment tests are run on every commit to `main` and on every PR tagged with `[static]` or `[ci]`.

apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/EnvironmentDefinition.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.lfdecentralizedtrust.splice.integration
22

33
import better.files.{File, Resource}
44
import com.digitalasset.canton.admin.api.client.data.User
5+
import com.digitalasset.canton.config.CantonRequireTypes.InstanceName
56
import com.digitalasset.canton.config.RequireTypes.{NonNegativeLong, NonNegativeNumeric}
67
import com.digitalasset.canton.config.{
78
ClockConfig,
@@ -358,6 +359,22 @@ case class EnvironmentDefinition(
358359
)(config)
359360
)
360361

362+
def withoutAliceValidatorConnectingToSplitwell: EnvironmentDefinition = {
363+
this
364+
.addConfigTransform((_, conf) =>
365+
conf.copy(validatorApps =
366+
conf.validatorApps.updatedWith(InstanceName.tryCreate("aliceValidator")) {
367+
_.map { aliceValidatorConfig =>
368+
val withoutExtraDomains = aliceValidatorConfig.domains.copy(extra = Seq.empty)
369+
aliceValidatorConfig.copy(
370+
domains = withoutExtraDomains
371+
)
372+
}
373+
}
374+
)
375+
)
376+
}
377+
361378
def clearConfigTransforms(): EnvironmentDefinition =
362379
copy(configTransformsWithContext = _ => Seq())
363380

apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/BootstrapPackageConfigDarUploadIntegrationTest.scala

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
package org.lfdecentralizedtrust.splice.integration.tests
55

6-
import com.digitalasset.canton.config.CantonRequireTypes.InstanceName
76
import com.digitalasset.canton.topology.SynchronizerId
87
import com.digitalasset.canton.topology.transaction.VettedPackage
98
import com.digitalasset.daml.lf.data.Ref.{PackageName, PackageVersion}
@@ -48,18 +47,7 @@ class BootstrapPackageConfigDarUploadIntegrationTest
4847
_.copy(initialPackageConfig = initialPackageConfig)
4948
)(config)
5049
)
51-
.addConfigTransform((_, conf) =>
52-
conf.copy(validatorApps =
53-
conf.validatorApps.updatedWith(InstanceName.tryCreate("aliceValidator")) {
54-
_.map { aliceValidatorConfig =>
55-
val withoutExtraSynchronizers = aliceValidatorConfig.domains.copy(extra = Seq.empty)
56-
aliceValidatorConfig.copy(
57-
domains = withoutExtraSynchronizers
58-
)
59-
}
60-
}
61-
)
62-
)
50+
.withoutAliceValidatorConnectingToSplitwell
6351
.withCantonNodeNameSuffix("BootstrapDsoPackageConfig")
6452
.withManualStart
6553

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package org.lfdecentralizedtrust.splice.integration.tests
2+
3+
import com.digitalasset.canton.HasExecutionContext
4+
import com.digitalasset.canton.admin.api.client.data.topology.ListOwnerToKeyMappingResult
5+
import com.digitalasset.canton.crypto.SigningPublicKey
6+
import com.digitalasset.canton.topology.Namespace
7+
import com.digitalasset.canton.topology.admin.grpc.TopologyStoreId
8+
import com.digitalasset.canton.topology.store.TimeQuery
9+
import org.lfdecentralizedtrust.splice.integration.EnvironmentDefinition
10+
import org.lfdecentralizedtrust.splice.integration.tests.SpliceTests.IntegrationTestWithSharedEnvironment
11+
import org.lfdecentralizedtrust.splice.util.WalletTestUtil
12+
13+
import scala.concurrent.duration.DurationInt
14+
15+
class ManualSignatureIntegrationTest
16+
extends IntegrationTestWithSharedEnvironment
17+
with HasExecutionContext
18+
with WalletTestUtil
19+
with WalletTxLogTestUtil {
20+
21+
override def environmentDefinition: EnvironmentDefinition = {
22+
EnvironmentDefinition
23+
.simpleTopology1Sv(this.getClass.getSimpleName)
24+
.withManualStart
25+
.withoutAliceValidatorConnectingToSplitwell
26+
.withSequencerConnectionsFromScanDisabled()
27+
}
28+
29+
"synchronizer" should {
30+
def checkLatestOTKKeysAreSigned(
31+
otks: Seq[ListOwnerToKeyMappingResult],
32+
namespace: Namespace,
33+
): Unit = {
34+
val otksForNs = otks
35+
.filter(_.item.member.namespace == namespace)
36+
val latestKeys = otksForNs
37+
.maxBy(_.context.serial)
38+
.item
39+
.keys
40+
.filter {
41+
case _: SigningPublicKey => true
42+
case _ => false
43+
}
44+
.map(_.id)
45+
.distinct
46+
val signatures = otksForNs.flatMap(_.context.signedBy).distinct
47+
latestKeys.diff(signatures) shouldBe empty
48+
}
49+
50+
"rotate SV' OTK mapping keys that are not signed." in { implicit env =>
51+
clue("sv1 starts.") {
52+
sv1Backend.startSync()
53+
}
54+
55+
eventuallySucceeds() {
56+
val synchronizerId = sv1Backend.participantClientWithAdminToken.synchronizers.id_of(
57+
sv1Backend.config.domains.global.alias
58+
)
59+
val store = TopologyStoreId.Synchronizer(synchronizerId)
60+
val otks = sv1Backend.participantClientWithAdminToken.topology.owner_to_key_mappings
61+
.list(store = Some(store), timeQuery = TimeQuery.Range(None, None))
62+
63+
clue("keys are rotated for sv1's sequencer.") {
64+
checkLatestOTKKeysAreSigned(otks, sv1Backend.sequencerClient.namespace)
65+
}
66+
clue("keys are rotated for sv1's mediator.") {
67+
checkLatestOTKKeysAreSigned(otks, sv1Backend.mediatorClient.namespace)
68+
}
69+
clue("keys are rotated for sv1's participant.") {
70+
checkLatestOTKKeysAreSigned(otks, sv1Backend.participantClient.namespace)
71+
}
72+
}
73+
74+
clue("sv1 shuts down.") {
75+
eventuallySucceeds() {
76+
sv1Backend.stop()
77+
}
78+
}
79+
}
80+
81+
"rotate validators' OTK mapping keys that are not signed." in { implicit env =>
82+
clue("Initialize the DSO") {
83+
initDsoWithSv1Only()
84+
}
85+
clue("Alice validator starts.") {
86+
aliceValidatorBackend.start()
87+
}
88+
89+
eventuallySucceeds(40.seconds) {
90+
val synchronizerId =
91+
aliceValidatorBackend.participantClientWithAdminToken.synchronizers.id_of(
92+
aliceValidatorBackend.config.domains.global.alias
93+
)
94+
val store = TopologyStoreId.Synchronizer(synchronizerId)
95+
val otks =
96+
aliceValidatorBackend.participantClientWithAdminToken.topology.owner_to_key_mappings
97+
.list(store = Some(store), timeQuery = TimeQuery.Range(None, None))
98+
99+
clue("keys are rotated for alice validator's participant.") {
100+
checkLatestOTKKeysAreSigned(otks, aliceValidatorBackend.participantClient.namespace)
101+
}
102+
}
103+
104+
clue("Alice validator and sv1 shut down.") {
105+
eventuallySucceeds() {
106+
aliceValidatorBackend.stop()
107+
sv1Backend.stop()
108+
}
109+
}
110+
}
111+
}
112+
}

apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/offlinekey/ValidatorOfflineRootNamespaceKeyIntegrationTest.scala

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.lfdecentralizedtrust.splice.integration.tests.offlinekey
22

3-
import com.digitalasset.canton.config.CantonRequireTypes.InstanceName
43
import com.digitalasset.canton.crypto.SigningKeyUsage
54
import com.digitalasset.canton.topology.admin.grpc.TopologyStoreId
65
import com.digitalasset.canton.topology.transaction.DelegationRestriction
@@ -45,18 +44,7 @@ class ValidatorOfflineRootNamespaceKeyIntegrationTest
4544
ConfigTransforms.bumpSomeWalletClientPortsBy(22_000, Seq("aliceWallet"))(config),
4645
)
4746
// By default, alice validator connects to the splitwell domain. This test doesn't start the splitwell node.
48-
.addConfigTransform((_, conf) =>
49-
conf.copy(validatorApps =
50-
conf.validatorApps.updatedWith(InstanceName.tryCreate("aliceValidator")) {
51-
_.map { aliceValidatorConfig =>
52-
val withoutExtraDomains = aliceValidatorConfig.domains.copy(extra = Seq.empty)
53-
aliceValidatorConfig.copy(
54-
domains = withoutExtraDomains
55-
)
56-
}
57-
}
58-
)
59-
)
47+
.withoutAliceValidatorConnectingToSplitwell
6048
.withTrafficTopupsDisabled
6149
.withManualStart
6250

apps/common/src/main/scala/org/lfdecentralizedtrust/splice/environment/TopologyAdminConnection.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,15 +512,15 @@ abstract class TopologyAdminConnection(
512512
forceChanges = ForceFlags.none,
513513
)
514514

515-
def listOwnerToKeyMapping(member: Member)(implicit
515+
def listOwnerToKeyMapping(member: Member, timeQuery: TimeQuery = TimeQuery.HeadState)(implicit
516516
traceContext: TraceContext
517517
): Future[Seq[TopologyResult[OwnerToKeyMapping]]] =
518518
runCmd(
519519
TopologyAdminCommands.Read.ListOwnerToKeyMapping(
520520
BaseQuery(
521521
store = AuthorizedStore,
522522
proposals = false,
523-
timeQuery = TimeQuery.HeadState,
523+
timeQuery = timeQuery,
524524
ops = None,
525525
filterSigningKey = "",
526526
protocolVersion = None,

0 commit comments

Comments
 (0)