Skip to content

Commit 77e8546

Browse files
Merge pull request #2491 from hyperledger-labs/oriol/mergemainto34
Merge main into canton-3.4
2 parents 5bec3ab + b9701c7 commit 77e8546

File tree

207 files changed

+4448
-1447
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

207 files changed

+4448
-1447
lines changed

.envrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ use_flake_subdir() {
1818
[[ -f .envrc.private ]] && [[ -z "$IGNORE_PRIVATE_ENVRC" ]] && source_env .envrc.private || true
1919

2020
# TODO(DACH-NY/canton-network-node#3876) work around for $TMPDIR is removed. #3876 to investigate more
21-
OLD_TMPDIR=$TMPDIR
21+
OLD_TMPDIR=${TMPDIR-unset}
2222

2323
use flake_subdir
2424

2525
# TODO(DACH-NY/canton-network-node#3876) work around for $TMPDIR is removed. #3876 to investigate more
26-
export TMPDIR=$OLD_TMPDIR
26+
[ $OLD_TMPDIR != "unset" ] && export TMPDIR=$OLD_TMPDIR
2727

2828
source_env .envrc.vars
2929

.github/actions/scripts/notification-scripts/failure_github_issue.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ def get_msg(self) -> tuple[str, str]:
2525
repo = Repo(search_parent_directories=True)
2626
commit_msg = repo.head.commit.summary
2727
commit_sha_short = GIT_SHA[:7]
28+
job_descriptor = (f"{self.args.job_subname} in " if self.args.job_subname else '') + self.args.job_name
2829

29-
title = f"GHA Run {self.args.gha_run_id} : job {self.args.job_name} Failed :fire:"
30+
title = f"GHA Run {self.args.gha_run_id} : job {job_descriptor} Failed :fire:"
3031
body = f"""
3132
[GitHub Actions Run]({job_url}).
33+
Job: {job_descriptor}
3234
Branch: [{self.args.branch}]({branch_url})
3335
Workflow: {self.args.gha_workflow_name}
3436
Commit: [{commit_sha_short}]({github_url}) {commit_msg}

.github/actions/scripts/notification-scripts/failure_notification_args.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class FailureArgs:
1313
dry_run: bool
1414
branch: str
1515
github_token: str
16+
job_subname: str
1617
# cci specific
1718
pipeline_id: str = ""
1819
workflow_id: str = ""
@@ -37,6 +38,7 @@ def parse_args() -> FailureArgs:
3738
parser.add_argument('--gha_run_id', default=os.environ.get('GITHUB_RUN_ID'))
3839
parser.add_argument('--gha_workflow_name', default=os.environ.get('GITHUB_WORKFLOW'))
3940
parser.add_argument('--job_name', default=os.environ.get('GITHUB_JOB'))
41+
parser.add_argument('--job_subname', default='')
4042
parser.add_argument('--branch', default=os.environ.get('GITHUB_HEAD_REF') or os.environ.get('GITHUB_REF'))
4143
else:
4244
parser.add_argument('--pipeline_id', default=os.environ.get('CIRCLE_PIPELINE_ID'))

.github/actions/tests/failure_notifications/action.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ description: Notify failures on Slack and create GitHub issues
44
# Note that this requires the `id-token` write permission to be set in the workflow
55

66
inputs:
7+
job_subname:
8+
description: "A more specific name for the job to report"
9+
required: false
10+
default: ""
711
workload_identity_provider:
812
description: "Workload identity provider"
913
required: true
@@ -38,4 +42,4 @@ runs:
3842
FAILURE_NOTIFICATIONS_URL: ${{ inputs.notifications_url }}
3943
NOTIFICATION_SLACK_CHANNEL: ${{ inputs.slack_channel }}
4044
shell: bash
41-
run: ./.github/actions/scripts/notification-scripts/failure_notification.py
45+
run: ./.github/actions/scripts/notification-scripts/failure_notification.py --job_subname "${{ inputs.job_subname }}"

.github/actions/tests/scala_test/action.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ runs:
302302
if: failure() && (github.event_name == 'push' || github.event_name == 'schedule')
303303
uses: ./.github/actions/tests/failure_notifications
304304
with:
305+
job_subname: "${{ inputs.test_suite_name }} (${{ inputs.runner_index }})"
305306
workload_identity_provider: "${{ inputs.google_workload_identity_provider }}"
306307
service_account: "${{ inputs.failure_notifications_invoker_sa }}"
307308
notifications_url: "${{ inputs.failure_notifications_invoker_url }}"

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ jobs:
238238
runs_on: self-hosted-docker-large
239239
test_names_file: 'test-full-class-names-local-net-based.log'
240240
parallelism: 1
241-
test_name: docker-compose
241+
test_name: local-net
242242
with_canton: false
243243
start_canton_options: ""
244244
commit_sha: ${{ inputs.commit_sha }}

LATEST_RELEASE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.4.17
1+
0.4.18

apps/app/src/main/scala/org/lfdecentralizedtrust/splice/config/SpliceConfig.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,10 @@ object SpliceConfig {
571571
deriveReader[BeneficiaryConfig]
572572
implicit val svParticipantClientConfigReader: ConfigReader[SvParticipantClientConfig] =
573573
deriveReader[SvParticipantClientConfig]
574+
implicit val amuletConversionRateFeedConfig: ConfigReader[AmuletConversionRateFeedConfig] =
575+
deriveReader[AmuletConversionRateFeedConfig]
576+
implicit val rangeConfig: ConfigReader[RangeConfig] =
577+
deriveReader[RangeConfig]
574578
implicit val svConfigReader: ConfigReader[SvAppBackendConfig] =
575579
deriveReader[SvAppBackendConfig].emap { conf =>
576580
def checkFoundDsoConfig(check: (SvAppBackendConfig, FoundDso) => Boolean) =
@@ -971,6 +975,10 @@ object SpliceConfig {
971975
deriveWriter[BeneficiaryConfig]
972976
implicit val svParticipantClientConfigWriter: ConfigWriter[SvParticipantClientConfig] =
973977
deriveWriter[SvParticipantClientConfig]
978+
implicit val amuletConversionRateFeedConfig: ConfigWriter[AmuletConversionRateFeedConfig] =
979+
deriveWriter[AmuletConversionRateFeedConfig]
980+
implicit val rangeConfig: ConfigWriter[RangeConfig] =
981+
deriveWriter[RangeConfig]
974982
implicit val svConfigWriter: ConfigWriter[SvAppBackendConfig] =
975983
deriveWriter[SvAppBackendConfig]
976984

apps/app/src/test/resources/frontend-config.jsonnet

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ local validatorNodes(clusterProtocol, clusterAddress, port) = {
4343
validator: { url: 'http://localhost:5503/api/validator' },
4444
wallet: { uiUrl: 'http://localhost:3000' },
4545
splitwell: { url: 'http://localhost:5113/api/splitwell' },
46-
scan: { url: 'http://localhost:5012/api/scan' },
46+
scan: { url: 'http://localhost:5012' },
4747
},
4848
bob: {
4949
jsonApiBackend: { url: 'http://127.0.0.1:6601' },
@@ -52,14 +52,14 @@ local validatorNodes(clusterProtocol, clusterAddress, port) = {
5252
validator: { url: 'http://localhost:5603/api/validator' },
5353
wallet: { uiUrl: 'http://localhost:3001' },
5454
splitwell: { url: 'http://localhost:5113/api/splitwell' },
55-
scan: { url: 'http://localhost:5012/api/scan' },
55+
scan: { url: 'http://localhost:5012' },
5656
},
5757
splitwell: {
5858
validator: { url: 'http://localhost:5703/api/validator' },
5959
wallet: { uiUrl: 'http://unused.com' },
6060
jsonApi: { url: 'http://unused.com/' },
6161
splitwell: { url: 'http://localhost:5113/api/splitwell' },
62-
scan: { url: 'http://localhost:5012/api/scan' },
62+
scan: { url: 'http://localhost:5012' },
6363
},
6464
preflight: {
6565
jsonApiBackend: { url: 'http://127.0.0.1:7575' },
@@ -68,30 +68,30 @@ local validatorNodes(clusterProtocol, clusterAddress, port) = {
6868
validator: { url: 'http://localhost:5003/api/validator' },
6969
wallet: { uiUrl: 'http://localhost:3000' },
7070
splitwell: { url: 'http://localhost:5113/api/splitwell' },
71-
scan: { url: clusterProtocol + '://' + 'scan.sv-2.' + clusterAddress + '/api/scan' },
71+
scan: { url: clusterProtocol + '://' + 'scan.sv-2.' + clusterAddress + '' },
7272
},
7373
scan: {
74-
scan: { url: 'http://localhost:5012/api/scan' },
74+
scan: { url: 'http://localhost:5012' },
7575
},
7676
sv1: {
7777
sv: { url: 'http://localhost:5114/api/sv' },
7878
validator: { url: 'http://localhost:5103/api/validator' },
79-
scan: { url: 'http://localhost:5012/api/scan' },
79+
scan: { url: 'http://localhost:5012' },
8080
},
8181
sv2: {
8282
sv: { url: 'http://localhost:5214/api/sv' },
8383
validator: { url: 'http://localhost:5103/api/validator' },
84-
scan: { url: 'http://localhost:5012/api/scan' },
84+
scan: { url: 'http://localhost:5012' },
8585
},
8686
sv3: {
8787
sv: { url: 'http://localhost:5314/api/sv' },
8888
validator: { url: 'http://localhost:5103/api/validator' },
89-
scan: { url: 'http://localhost:5012/api/scan' },
89+
scan: { url: 'http://localhost:5012' },
9090
},
9191
sv4: {
9292
sv: { url: 'http://localhost:5414/api/sv' },
9393
validator: { url: 'http://localhost:5103/api/validator' },
94-
scan: { url: 'http://localhost:5012/api/scan' },
94+
scan: { url: 'http://localhost:5012' },
9595
},
9696
};
9797

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package org.lfdecentralizedtrust.splice.integration.plugins
2+
3+
import cats.data.Chain
4+
import org.lfdecentralizedtrust.splice.console.ScanAppBackendReference
5+
import org.lfdecentralizedtrust.splice.environment.SpliceEnvironment
6+
import org.lfdecentralizedtrust.splice.http.v0.definitions.DamlValueEncoding.members.CompactJson
7+
import org.lfdecentralizedtrust.splice.http.v0.definitions.EventHistoryItem
8+
import org.lfdecentralizedtrust.splice.http.v0.definitions.UpdateHistoryItemV2.members
9+
import org.lfdecentralizedtrust.splice.http.v0.definitions.UpdateHistoryReassignment.Event.members as reassignmentMembers
10+
import org.lfdecentralizedtrust.splice.integration.tests.SpliceTests.SpliceTestConsoleEnvironment
11+
import com.digitalasset.canton.ScalaFuturesWithPatience
12+
import com.digitalasset.canton.integration.EnvironmentSetupPlugin
13+
import com.digitalasset.canton.logging.NamedLoggerFactory
14+
import org.lfdecentralizedtrust.splice.config.SpliceConfig
15+
import org.scalatest.{Inspectors, LoneElement}
16+
import org.scalatest.concurrent.Eventually
17+
import org.scalatest.matchers.should.Matchers
18+
19+
import scala.annotation.tailrec
20+
21+
class EventHistorySanityCheckPlugin(
22+
protected val loggerFactory: NamedLoggerFactory
23+
) extends EnvironmentSetupPlugin[SpliceConfig, SpliceEnvironment]
24+
with Matchers
25+
with Eventually
26+
with Inspectors
27+
with ScalaFuturesWithPatience
28+
with LoneElement {
29+
30+
override def beforeEnvironmentDestroyed(
31+
config: SpliceConfig,
32+
environment: SpliceTestConsoleEnvironment,
33+
): Unit = {
34+
val initializedScans = environment.scans.local.filter(_.is_initialized)
35+
if (initializedScans.nonEmpty) {
36+
compareEventHistories(initializedScans)
37+
}
38+
}
39+
40+
@tailrec
41+
private def paginateEventHistory(
42+
scan: ScanAppBackendReference,
43+
after: Option[(Long, String)],
44+
acc: Chain[EventHistoryItem],
45+
): Chain[EventHistoryItem] = {
46+
val result = scan.getEventHistory(10, after, encoding = CompactJson)
47+
val newAcc = acc ++ Chain.fromSeq(result)
48+
if (result.isEmpty) newAcc
49+
else {
50+
result.lastOption.flatMap(eventCursor) match {
51+
case Some(nextAfter) =>
52+
paginateEventHistory(scan, Some(nextAfter), newAcc)
53+
case None => newAcc
54+
}
55+
}
56+
}
57+
58+
private def compareEventHistories(
59+
scans: Seq[ScanAppBackendReference]
60+
): Unit = {
61+
val (founders, others) = scans.partition(_.config.isFirstSv)
62+
val founder = founders.loneElement
63+
val founderHistory = paginateEventHistory(founder, None, Chain.empty).toVector
64+
forAll(others) { otherScan =>
65+
val otherScanHistory = paginateEventHistory(otherScan, None, Chain.empty).toVector
66+
val minSize = Math.min(founderHistory.size, otherScanHistory.size)
67+
val otherComparable = otherScanHistory.take(minSize)
68+
val founderComparable = founderHistory.take(minSize)
69+
val different = otherComparable
70+
.zip(founderComparable)
71+
.collect {
72+
case (otherItem, founderItem) if founderItem != otherItem =>
73+
otherItem -> founderItem
74+
}
75+
76+
different should be(empty)
77+
}
78+
}
79+
80+
private def eventCursor(item: EventHistoryItem): Option[(Long, String)] = {
81+
val updateCursor = item.update.flatMap {
82+
case members.UpdateHistoryTransactionV2(tx) =>
83+
Some((tx.migrationId, tx.recordTime))
84+
case members.UpdateHistoryReassignment(reassignment) =>
85+
reassignment.event match {
86+
case reassignmentMembers.UpdateHistoryAssignment(event) =>
87+
Some((event.migrationId, reassignment.recordTime))
88+
case reassignmentMembers.UpdateHistoryUnassignment(event) =>
89+
Some((event.migrationId, reassignment.recordTime))
90+
}
91+
}
92+
updateCursor.orElse(item.verdict.map(v => (v.migrationId, v.recordTime)))
93+
}
94+
}

0 commit comments

Comments
 (0)