@@ -10,12 +10,13 @@ import org.lfdecentralizedtrust.splice.integration.tests.SpliceTests.Integration
1010import org .lfdecentralizedtrust .splice .sv .automation .delegatebased .{
1111 AdvanceOpenMiningRoundTrigger ,
1212 ExpireIssuingMiningRoundTrigger ,
13+ FeaturedAppActivityMarkerTrigger ,
1314}
1415import org .lfdecentralizedtrust .splice .util .*
1516import com .digitalasset .canton .config .NonNegativeFiniteDuration
1617import org .lfdecentralizedtrust .splice .codegen .java .splice .amulet
1718import org .lfdecentralizedtrust .splice .codegen .java .splice .api .featuredapprightv1
18- import org . lfdecentralizedtrust . splice . wallet . store . TransferTxLogEntry
19+
1920import scala .jdk .CollectionConverters .*
2021
2122@ org.lfdecentralizedtrust.splice.util.scalatesttags.SpliceAmulet_0_1_9
@@ -28,7 +29,8 @@ class FeaturedAppActivityMarkerIntegrationTest
2829
2930 override def environmentDefinition : SpliceEnvironmentDefinition =
3031 EnvironmentDefinition
31- .simpleTopology1Sv(this .getClass.getSimpleName)
32+ // Using 4Svs so that we see whether they manage to jointly complete all work
33+ .simpleTopology4Svs(this .getClass.getSimpleName)
3234 .addConfigTransforms((_, config) =>
3335 ConfigTransforms .updateAllSvAppFoundDsoConfigs_(
3436 _.copy(
@@ -44,6 +46,15 @@ class FeaturedAppActivityMarkerIntegrationTest
4446 updateAutomationConfig(ConfigurableApp .Sv )(
4547 _.withPausedTrigger[AdvanceOpenMiningRoundTrigger ]
4648 .withPausedTrigger[ExpireIssuingMiningRoundTrigger ]
49+ .withPausedTrigger[FeaturedAppActivityMarkerTrigger ]
50+ )(config)
51+ )
52+ .addConfigTransforms((_, config) =>
53+ ConfigTransforms .updateAllSvAppConfigs_(
54+ _.copy(
55+ delegatelessAutomationFeaturedAppActivityMarkerCatchupThreshold = 10 ,
56+ delegatelessAutomationFeaturedAppActivityMarkerBatchSize = 2 ,
57+ )
4758 )(config)
4859 )
4960
@@ -58,92 +69,79 @@ class FeaturedAppActivityMarkerIntegrationTest
5869 .selfGrantFeaturedAppRight()
5970 .toInterface(featuredapprightv1.FeaturedAppRight .INTERFACE )
6071
72+ val markerMultiplier = 10
73+
6174 actAndCheck(
6275 " Create activity markers" , {
63- aliceValidatorBackend.participantClientWithAdminToken.ledger_api_extensions.commands
64- .submitJava(
65- Seq (alice),
66- commands = aliceFeaturedAppRightCid
67- .exerciseFeaturedAppRight_CreateActivityMarker(
68- Seq (
69- new featuredapprightv1.AppRewardBeneficiary (
70- alice.toProtoPrimitive,
71- BigDecimal (0.2 ).bigDecimal,
72- ),
73- new featuredapprightv1.AppRewardBeneficiary (
74- charlie.toProtoPrimitive,
75- BigDecimal (0.8 ).bigDecimal,
76- ),
77- ).asJava
78- )
79- .commands
80- .asScala
81- .toSeq,
82- )
83-
84- bobValidatorBackend.participantClientWithAdminToken.ledger_api_extensions.commands
85- .submitJava(
86- Seq (bob),
87- commands = bobFeaturedAppRightCid
88- .exerciseFeaturedAppRight_CreateActivityMarker(
89- Seq (
90- new featuredapprightv1.AppRewardBeneficiary (
91- bob.toProtoPrimitive,
92- BigDecimal (1.0 ).bigDecimal,
93- )
94- ).asJava
95- )
96- .commands
97- .asScala
98- .toSeq,
99- )
76+ for (i <- 1 to markerMultiplier) {
77+ aliceValidatorBackend.participantClientWithAdminToken.ledger_api_extensions.commands
78+ .submitJava(
79+ Seq (alice),
80+ commands = aliceFeaturedAppRightCid
81+ .exerciseFeaturedAppRight_CreateActivityMarker(
82+ Seq (
83+ new featuredapprightv1.AppRewardBeneficiary (
84+ alice.toProtoPrimitive,
85+ BigDecimal (0.2 ).bigDecimal,
86+ ),
87+ new featuredapprightv1.AppRewardBeneficiary (
88+ charlie.toProtoPrimitive,
89+ BigDecimal (0.8 ).bigDecimal,
90+ ),
91+ ).asJava
92+ )
93+ .commands
94+ .asScala
95+ .toSeq,
96+ )
97+ bobValidatorBackend.participantClientWithAdminToken.ledger_api_extensions.commands
98+ .submitJava(
99+ Seq (bob),
100+ commands = bobFeaturedAppRightCid
101+ .exerciseFeaturedAppRight_CreateActivityMarker(
102+ Seq (
103+ new featuredapprightv1.AppRewardBeneficiary (
104+ bob.toProtoPrimitive,
105+ BigDecimal (1.0 ).bigDecimal,
106+ )
107+ ).asJava
108+ )
109+ .commands
110+ .asScala
111+ .toSeq,
112+ )
113+ }
114+ // unpause all activity marker triggers here, so they can start to get to work
115+ env.svs.local.foreach(
116+ _.dsoDelegateBasedAutomation.trigger[FeaturedAppActivityMarkerTrigger ].resume()
117+ )
100118 },
101119 )(
102120 " Activity markers are converted to reward coupons" ,
103121 _ => {
104- aliceValidatorBackend.participantClientWithAdminToken.ledger_api_extensions.acs.filterJava(
105- amulet.AppRewardCoupon .COMPANION
106- )(alice, c => c.data.provider == alice.toProtoPrimitive) should have size 2
107- bobValidatorBackend.participantClientWithAdminToken.ledger_api_extensions.acs.filterJava(
108- amulet.AppRewardCoupon .COMPANION
109- )(bob, c => c.data.provider == bob.toProtoPrimitive) should have size 1
110- },
111- )
112-
113- // Advance three times so the round the coupons are assigned to is issuing
114- actAndCheck(
115- " Advance until reward coupon round is issuing" , {
116- advanceRoundsByOneTickViaAutomation()
117- advanceRoundsByOneTickViaAutomation()
118- advanceRoundsByOneTickViaAutomation()
119- },
120- )(
121- " Rewards are minted" ,
122- _ => {
123- aliceValidatorBackend.participantClientWithAdminToken.ledger_api_extensions.acs.filterJava(
124- amulet.AppRewardCoupon .COMPANION
125- )(alice, c => c.data.provider == alice.toProtoPrimitive) shouldBe empty
126- bobValidatorBackend.participantClientWithAdminToken.ledger_api_extensions.acs.filterJava(
127- amulet.AppRewardCoupon .COMPANION
128- )(bob, c => c.data.provider == bob.toProtoPrimitive) shouldBe empty
129-
130- // Check that tx logs work as expected, the exact amounts are just based on testing, the important part is alice sees only the minting for the reward she is a beneficiary on
131- // and not the one for charlie even though she is the provider and the maounts of alice and charlie add up to bob.
122+ sv1Backend.participantClientWithAdminToken.ledger_api_extensions.acs.filterJava(
123+ amulet.FeaturedAppActivityMarker .COMPANION
124+ )(dsoParty, _ => true ) should have size 0
132125 inside(
133- aliceWalletClient.listTransactions(beginAfterId = None , pageSize = 1000 ).loneElement
134- ) { case transfer : TransferTxLogEntry =>
135- transfer.appRewardsUsed should beAround(9.0 )
126+ aliceValidatorBackend.participantClientWithAdminToken.ledger_api_extensions.acs
127+ .filterJava(
128+ amulet.AppRewardCoupon .COMPANION
129+ )(alice, c => c.data.provider == alice.toProtoPrimitive)
130+ ) { aliceCoupons =>
131+ // The actual number of coupons is non-deterministic due to the random sampling and
132+ // the batches only creating one coupon per beneficiary. There are at least two, as there are two beneficiaries.
133+ aliceCoupons.size should be >= 2
134+ val totalWeight : BigDecimal = aliceCoupons.map(co => BigDecimal (co.data.amount)).sum
135+ totalWeight shouldBe BigDecimal (markerMultiplier)
136136 }
137-
138137 inside(
139- charlieWalletClient.listTransactions(beginAfterId = None , pageSize = 1000 ).loneElement
140- ) { case transfer : TransferTxLogEntry =>
141- transfer.appRewardsUsed should beAround(38.0 )
142- }
143-
144- inside(bobWalletClient.listTransactions(beginAfterId = None , pageSize = 1000 ).loneElement) {
145- case transfer : TransferTxLogEntry =>
146- transfer.appRewardsUsed should beAround(47.0 )
138+ bobValidatorBackend.participantClientWithAdminToken.ledger_api_extensions.acs.filterJava(
139+ amulet.AppRewardCoupon .COMPANION
140+ )(bob, c => c.data.provider == bob.toProtoPrimitive)
141+ ) { bobCoupons =>
142+ bobCoupons.size should be >= 1
143+ val totalWeight : BigDecimal = bobCoupons.map(co => BigDecimal (co.data.amount)).sum
144+ totalWeight shouldBe BigDecimal (markerMultiplier)
147145 }
148146 },
149147 )
0 commit comments