Skip to content

Commit 34247c6

Browse files
canton-network-daDA Automation
andauthored
Update Splice from CCI (#350)
Signed-off-by: DA Automation <splice-maintainers@digitalasset.com> Co-authored-by: DA Automation <splice-maintainers@digitalasset.com>
1 parent 840d957 commit 34247c6

File tree

53 files changed

+5657
-4018
lines changed

Some content is hidden

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

53 files changed

+5657
-4018
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ local testAuth(enabled, auth0Config) =
3737

3838
local validatorNodes(clusterProtocol, clusterAddress, port) = {
3939
alice: {
40-
jsonApiBackend: { url: 'http://127.0.0.1:6201' },
40+
jsonApiBackend: { url: 'http://127.0.0.1:6501' },
4141
jsonApi: { url: 'http://localhost:' + port + '/api/json-api/' },
4242
participantAdmin: { url: 'http://localhost:6202' },
4343
validator: { url: 'http://localhost:5503/api/validator' },
@@ -46,7 +46,7 @@ local validatorNodes(clusterProtocol, clusterAddress, port) = {
4646
scan: { url: 'http://localhost:5012/api/scan' },
4747
},
4848
bob: {
49-
jsonApiBackend: { url: 'http://127.0.0.1:6301' },
49+
jsonApiBackend: { url: 'http://127.0.0.1:6601' },
5050
jsonApi: { url: 'http://localhost:' + port + '/api/json-api/' },
5151
participantAdmin: { url: 'http://localhost:6302' },
5252
validator: { url: 'http://localhost:5603/api/validator' },

apps/app/src/test/resources/simple-topology-canton-simtime.conf

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,65 @@ _participant_template.testing-time.type = monotonic-time
77
_sv1Participant_client {
88
admin-api.port = 15102
99
ledger-api.port = 15101
10+
http-ledger-api {
11+
server.port = 16101
12+
allow-insecure-tokens = true
13+
}
1014
}
1115

1216
_sv2Participant_client {
1317
admin-api.port = 15202
1418
ledger-api.port = 15201
19+
http-ledger-api {
20+
server.port = 16201
21+
allow-insecure-tokens = true
22+
}
1523
}
1624

1725
_sv3Participant_client {
1826
admin-api.port = 15302
1927
ledger-api.port = 15301
28+
http-ledger-api {
29+
server.port = 16301
30+
allow-insecure-tokens = true
31+
}
2032
}
2133

2234
_sv4Participant_client {
2335
admin-api.port = 15402
2436
ledger-api.port = 15401
37+
http-ledger-api {
38+
server.port = 16401
39+
allow-insecure-tokens = true
40+
}
2541
}
2642

2743
_aliceParticipant_client {
2844
admin-api.port = 15502
2945
ledger-api.port = 15501
3046
# Used in token standard tests
3147
http-ledger-api {
32-
server.port = 16201
48+
server.port = 16501
3349
allow-insecure-tokens = true
3450
}
3551
}
3652

3753
_bobParticipant_client {
3854
admin-api.port = 15602
3955
ledger-api.port = 15601
40-
# Unused so just disable it
41-
http-ledger-api = null
56+
http-ledger-api {
57+
server.port = 16601
58+
allow-insecure-tokens = true
59+
}
4260
}
4361

4462
_splitwellParticipant_client {
4563
admin-api.port = 15702
4664
ledger-api.port = 15701
47-
# Unused so just disable it
48-
http-ledger-api = null
65+
http-ledger-api {
66+
server.port = 16701
67+
allow-insecure-tokens = true
68+
}
4969
}
5070

5171
_sv1Sequencer_client {

apps/app/src/test/resources/simple-topology-canton.conf

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,44 @@ include required("include/participants.conf")
66
_sv1Participant_client {
77
admin-api.port = 5102
88
ledger-api.port = 5101
9+
http-ledger-api {
10+
server.port = 6101
11+
allow-insecure-tokens = true
12+
}
913
}
1014

1115
_sv2Participant_client {
1216
admin-api.port = 5202
1317
ledger-api.port = 5201
18+
http-ledger-api {
19+
server.port = 6201
20+
allow-insecure-tokens = true
21+
}
1422
}
1523

1624
_sv3Participant_client {
1725
admin-api.port = 5302
1826
ledger-api.port = 5301
27+
http-ledger-api {
28+
server.port = 6301
29+
allow-insecure-tokens = true
30+
}
1931
}
2032

2133
_sv4Participant_client {
2234
admin-api.port = 5402
2335
ledger-api.port = 5401
36+
http-ledger-api {
37+
server.port = 6401
38+
allow-insecure-tokens = true
39+
}
2440
}
2541

2642
_aliceParticipant_client {
2743
admin-api.port = 5502
2844
ledger-api.port = 5501
2945
http-ledger-api {
30-
server.port = 6201
46+
server.port = 6501
3147
allow-insecure-tokens = true
3248
}
3349
}
@@ -36,7 +52,7 @@ _bobParticipant_client {
3652
admin-api.port = 5602
3753
ledger-api.port = 5601
3854
http-ledger-api {
39-
server.port = 6301
55+
server.port = 6601
4056
allow-insecure-tokens = true
4157
}
4258
}
@@ -45,7 +61,7 @@ _splitwellParticipant_client {
4561
admin-api.port = 5702
4662
ledger-api.port = 5701
4763
http-ledger-api {
48-
server.port = 6401
64+
server.port = 6701
4965
allow-insecure-tokens = true
5066
}
5167
}
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
package org.lfdecentralizedtrust.splice.integration.plugins
2+
3+
import com.daml.ledger.javaapi.data.Identifier
4+
import com.digitalasset.canton.ScalaFuturesWithPatience
5+
import com.digitalasset.canton.integration.EnvironmentSetupPlugin
6+
import com.digitalasset.canton.logging.SuppressingLogger
7+
import com.digitalasset.canton.topology.PartyId
8+
import com.digitalasset.canton.tracing.TraceContext
9+
import org.lfdecentralizedtrust.splice.config.SpliceConfig
10+
import org.lfdecentralizedtrust.splice.environment.SpliceEnvironment
11+
import org.lfdecentralizedtrust.splice.integration.tests.SpliceTests.SpliceTestConsoleEnvironment
12+
import org.lfdecentralizedtrust.splice.util.CommonAppInstanceReferences
13+
import org.scalatest.concurrent.Eventually
14+
import org.scalatest.matchers.should.Matchers
15+
import org.scalatest.{Inside, Inspectors, LoneElement}
16+
17+
import scala.collection.mutable
18+
import scala.sys.process.{Process, ProcessLogger}
19+
20+
import java.nio.file.Files
21+
import java.util.UUID
22+
import TokenStandardCliSanityCheckPlugin.*
23+
24+
import scala.collection.parallel.CollectionConverters.*
25+
import scala.util.control.NonFatal
26+
import scala.util.{Success, Try}
27+
28+
/** Runs `token-standard/cli`, to make sure that we have:
29+
* - no transactions that would break it.
30+
* - no transactions that get parsed as raw creates/archives,
31+
* as they should all be under some known/parseable exercise.
32+
* Unless their templates are ignored in `rawBehavior`,
33+
* in which case we know they're created via ledger API on purpose.
34+
*/
35+
class TokenStandardCliSanityCheckPlugin(
36+
rawBehavior: OutputCreateArchiveBehavior,
37+
protected val loggerFactory: SuppressingLogger,
38+
) extends EnvironmentSetupPlugin[SpliceConfig, SpliceEnvironment]
39+
with Matchers
40+
with Eventually
41+
with Inspectors
42+
with ScalaFuturesWithPatience
43+
with LoneElement
44+
with Inside
45+
with CommonAppInstanceReferences {
46+
47+
override def beforeEnvironmentDestroyed(
48+
config: SpliceConfig,
49+
environment: SpliceTestConsoleEnvironment,
50+
): Unit = {
51+
try {
52+
TraceContext.withNewTraceContext { implicit tc =>
53+
// `SuppressingLogger.suppress` support neither nested nor **concurrent** calls
54+
// but we need it for (expected) connection errors
55+
loggerFactory.suppressWarningsAndErrors {
56+
// Using `par` to save some time per test
57+
environment.wallets.par.foreach { wallet =>
58+
val ledgerApiUser = wallet.config.ledgerApiUser
59+
val validator = environment.validators.local
60+
.find(_.config.adminApi.port.unwrap == wallet.config.adminApi.url.effectivePort)
61+
.getOrElse(
62+
throw new RuntimeException(s"Failed to find validator for wallet of $ledgerApiUser")
63+
)
64+
// JSON API port = gRPCport + 1000
65+
val participantHttpApiPort =
66+
validator.participantClient.config.ledgerApi.port.unwrap + 1000
67+
68+
if (
69+
validator.config.enableWallet &&
70+
Try(wallet.httpLive && validator.participantClient.health.is_running())
71+
.getOrElse(false)
72+
) {
73+
// Sometimes userStatus will fail with 404
74+
Try(wallet.userStatus()) match {
75+
case Success(userStatus)
76+
if userStatus.userOnboarded && userStatus.userWalletInstalled =>
77+
val party = PartyId.tryFromProtoPrimitive(userStatus.party)
78+
val authToken = wallet.token.getOrElse(
79+
throw new IllegalStateException(
80+
s"No auth token found for wallet of ${party.toProtoPrimitive}"
81+
)
82+
)
83+
// check no command blows up
84+
runCommand("list-holdings", party, authToken, participantHttpApiPort, Seq.empty)
85+
val holdingTxsDebugPath =
86+
Files.createTempFile(UUID.randomUUID().toString, ".json")
87+
logger.info(
88+
s"Debug Output of token-standard command list-holding-txs will be written to $holdingTxsDebugPath"
89+
)
90+
// check also that list-holding-txs does not contain raw events
91+
val holdingTxsExtraArgs =
92+
Seq("-d", holdingTxsDebugPath.toAbsolutePath.toString) ++ (rawBehavior match {
93+
case OutputCreateArchiveBehavior.IgnoreAll => Seq.empty
94+
case OutputCreateArchiveBehavior.IgnoreForTemplateIds(templateIds) =>
95+
Seq("--strict") ++ templateIds.headOption.toList.flatMap(tId =>
96+
Seq("--strict-ignore", tId.getEntityName) ++ templateIds.tail
97+
.map(_.getEntityName)
98+
)
99+
})
100+
runCommand(
101+
"list-holding-txs",
102+
party,
103+
authToken,
104+
participantHttpApiPort,
105+
holdingTxsExtraArgs,
106+
)
107+
case result =>
108+
logger.info(
109+
s"Not checking wallet for user $ledgerApiUser because it's not available: $result"
110+
)
111+
}
112+
} else {
113+
logger.info(
114+
s"Token-standard CLI not running for $ledgerApiUser because either wallet or participant are not alive."
115+
)
116+
}
117+
}
118+
}
119+
}
120+
} catch {
121+
case NonFatal(ex) =>
122+
val msg = "Failed to run token-standard sanity check"
123+
logger.error(msg)(TraceContext.empty)
124+
throw new RuntimeException(msg, ex)
125+
}
126+
}
127+
128+
private def runCommand(
129+
command: String,
130+
partyId: PartyId,
131+
token: String,
132+
participantPort: Int,
133+
extraArgs: Seq[String],
134+
)(implicit
135+
tc: TraceContext
136+
): String = {
137+
val readLines = mutable.Buffer[String]()
138+
val logProcessor = ProcessLogger { line =>
139+
{
140+
logger.debug(s"CLI output: $line")
141+
readLines.append(line)
142+
}
143+
}
144+
val cwd = new java.io.File("token-standard/cli")
145+
146+
val args = Seq(
147+
"npm",
148+
"run",
149+
"cli",
150+
"--",
151+
command,
152+
partyId.toProtoPrimitive,
153+
"-l",
154+
s"http://localhost:$participantPort",
155+
"-a",
156+
token,
157+
) ++ extraArgs
158+
val exitCodeTry = Try(Process(args, cwd).!(logProcessor))
159+
if (exitCodeTry.toOption.exists(_ != 0) || exitCodeTry.isFailure) {
160+
logger.error(s"Failed to run $args: $exitCodeTry. Dumping output.")(TraceContext.empty)
161+
readLines.foreach(logger.error(_)(TraceContext.empty))
162+
// sometimes readlines is empty...?
163+
throw new RuntimeException(s"$args failed: ${readLines}")
164+
}
165+
val result = readLines
166+
.dropWhile(line => !line.startsWith("[") && !line.startsWith("{")) // remove npm noise
167+
.mkString("\n")
168+
val tmpFile = Files.createTempFile(UUID.randomUUID().toString, ".json")
169+
Files.writeString(tmpFile, result)
170+
logger.debug(s"Output of token-standard command $command written to $tmpFile")
171+
result
172+
}
173+
174+
}
175+
176+
object TokenStandardCliSanityCheckPlugin {
177+
sealed trait OutputCreateArchiveBehavior
178+
object OutputCreateArchiveBehavior {
179+
180+
/** Presence of a type:"Created"|"Archived" will fail unless explicitly ignored in the Seq.
181+
*/
182+
case class IgnoreForTemplateIds(templateIds: Seq[Identifier])
183+
extends OutputCreateArchiveBehavior
184+
185+
/** The CLI will still be run, making sure that it doesn't crash, but its output won't be validated.
186+
*/
187+
case object IgnoreAll extends OutputCreateArchiveBehavior
188+
}
189+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ class AnsAuth0FrontendIntegrationTest
1515
with AnsFrontendTestUtil
1616
with FrontendLoginUtil {
1717

18+
// The change of the authyority appears to break the JSON API and causes "The supplied authentication is invalid"
19+
override protected def runTokenStandardCliSanityCheck: Boolean = false
20+
1821
override def environmentDefinition
1922
: org.lfdecentralizedtrust.splice.integration.EnvironmentDefinition =
2023
EnvironmentDefinition

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class AnsIntegrationTest extends IntegrationTest with WalletTestUtil with Trigge
6464
sv1Backend.dsoDelegateBasedAutomation.trigger[ExpiredAnsEntryTrigger]
6565

6666
// created by the expiry test
67-
override protected lazy val updateHistoryIgnoredRootCreates: Seq[Identifier] = Seq(
67+
override protected lazy val sanityChecksIgnoredRootCreates: Seq[Identifier] = Seq(
6868
codegen.AnsEntry.TEMPLATE_ID_WITH_PACKAGE_ID
6969
)
7070

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import org.lfdecentralizedtrust.splice.console.{
2626
}
2727
import org.lfdecentralizedtrust.splice.environment.{DarResources, PackageIdResolver}
2828
import org.lfdecentralizedtrust.splice.integration.EnvironmentDefinition
29+
import org.lfdecentralizedtrust.splice.integration.plugins.TokenStandardCliSanityCheckPlugin
2930
import org.lfdecentralizedtrust.splice.integration.tests.SpliceTests.{
3031
IntegrationTest,
3132
SpliceTestConsoleEnvironment,
@@ -47,6 +48,12 @@ class BootstrapPackageConfigIntegrationTest
4748
with SplitwellTestUtil
4849
with StandaloneCanton {
4950

51+
// this test starts up on older version (see initialPackageConfig), which don't define token-standard interfaces
52+
// and thus everything will show up as raw create/archives.
53+
override protected lazy val tokenStandardCliBehavior
54+
: TokenStandardCliSanityCheckPlugin.OutputCreateArchiveBehavior =
55+
TokenStandardCliSanityCheckPlugin.OutputCreateArchiveBehavior.IgnoreAll
56+
5057
override def dbsSuffix = "bootstrapdso"
5158

5259
// Runs against a temporary Canton instance.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ class ExternalPartySetupProposalIntegrationTest
5959
with TriggerTestUtil
6060
with ExternallySignedPartyTestUtil {
6161

62-
override lazy val updateHistoryIgnoredRootExercises = Seq(
62+
override lazy val sanityChecksIgnoredRootExercises = Seq(
6363
(TransferPreapproval.TEMPLATE_ID_WITH_PACKAGE_ID, "Archive")
6464
)
6565

66-
override lazy val updateHistoryIgnoredRootCreates = Seq(
66+
override lazy val sanityChecksIgnoredRootCreates = Seq(
6767
TransferPreapproval.TEMPLATE_ID_WITH_PACKAGE_ID,
6868
amuletCodegen.AppRewardCoupon.TEMPLATE_ID_WITH_PACKAGE_ID,
6969
)

0 commit comments

Comments
 (0)