-
Notifications
You must be signed in to change notification settings - Fork 50
[ci] Zero balance related fields in round aggregates so that they always agree (BFT) #3204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
029401d
23d08e3
35b6cf6
be5e147
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,11 +30,13 @@ import org.lfdecentralizedtrust.splice.environment.{ | |
| SpliceLedgerClient, | ||
| } | ||
| import org.lfdecentralizedtrust.splice.http.v0.definitions.ErrorResponse | ||
|
|
||
| import org.lfdecentralizedtrust.splice.scan.admin.api.client.BftScanConnection.Bft | ||
| import org.lfdecentralizedtrust.splice.scan.admin.api.client.commands.HttpScanAppClient.{ | ||
| DomainScans, | ||
| DsoScan, | ||
| } | ||
| import org.lfdecentralizedtrust.splice.scan.admin.http.HttpScanHandler | ||
| import org.lfdecentralizedtrust.splice.scan.config.ScanAppClientConfig | ||
| import org.lfdecentralizedtrust.splice.store.HistoryBackfilling.SourceMigrationInfo | ||
| import org.lfdecentralizedtrust.splice.store.MultiDomainAcsStore.ContractState | ||
|
|
@@ -54,6 +56,7 @@ import org.slf4j.event.Level | |
| import java.time.{Duration, Instant} | ||
| import java.util.concurrent.atomic.AtomicInteger | ||
| import scala.concurrent.{ExecutionContext, Future} | ||
| import scala.util.Random | ||
|
|
||
| // mock verification triggers this | ||
| @SuppressWarnings(Array("com.digitalasset.canton.DiscardedFuture")) | ||
|
|
@@ -922,6 +925,93 @@ class BftScanConnectionTest | |
| result shouldBe Some(roundAggregate) | ||
| } | ||
|
|
||
| "get BFT round aggregates from scans, ignoring balance fields" in { | ||
| val round = 0L | ||
| def randomValue = BigDecimal(Random.nextInt(50) + 1) | ||
| def mkRoundTotals() = RoundTotals( | ||
| closedRound = round, | ||
| closedRoundEffectiveAt = CantonTimestamp.MinValue, | ||
| appRewards = BigDecimal(100), | ||
| validatorRewards = BigDecimal(150), | ||
| changeToInitialAmountAsOfRoundZero = randomValue, | ||
| changeToHoldingFeesRate = randomValue, | ||
| cumulativeAppRewards = BigDecimal(1100), | ||
| cumulativeValidatorRewards = BigDecimal(1150), | ||
| cumulativeChangeToInitialAmountAsOfRoundZero = randomValue, | ||
| cumulativeChangeToHoldingFeesRate = randomValue, | ||
| totalAmuletBalance = randomValue, | ||
| ) | ||
| def mkRoundPartyTotals() = RoundPartyTotals( | ||
| closedRound = round, | ||
| party = "party-id", | ||
| appRewards = BigDecimal(10), | ||
| validatorRewards = BigDecimal(20), | ||
| trafficPurchased = 10L, | ||
| trafficPurchasedCcSpent = BigDecimal(30), | ||
| trafficNumPurchases = 30L, | ||
| cumulativeAppRewards = BigDecimal(40), | ||
| cumulativeValidatorRewards = BigDecimal(50), | ||
| cumulativeChangeToInitialAmountAsOfRoundZero = randomValue, | ||
| cumulativeChangeToHoldingFeesRate = randomValue, | ||
| cumulativeTrafficPurchased = 50L, | ||
| cumulativeTrafficPurchasedCcSpent = BigDecimal(70), | ||
| cumulativeTrafficNumPurchases = 70L, | ||
| ) | ||
| def mkRoundAggregateUsingDecoder() = RoundAggregate( | ||
| ScanRoundAggregatesDecoder | ||
| .decodeRoundTotal(HttpScanHandler.encodeRoundTotals(mkRoundTotals())) | ||
| .value, | ||
| Vector( | ||
| ScanRoundAggregatesDecoder | ||
| .decodeRoundPartyTotals(HttpScanHandler.encodeRoundPartyTotals(mkRoundPartyTotals())) | ||
| .value | ||
| ), | ||
| ) | ||
| def mkRoundAggregateWithoutDecoder() = RoundAggregate( | ||
| mkRoundTotals(), | ||
| Vector(mkRoundPartyTotals()), | ||
| ) | ||
| val roundAggregateZeroBalanceValues = mkRoundAggregateWithoutDecoder().copy( | ||
| roundTotals = mkRoundAggregateWithoutDecoder().roundTotals.copy( | ||
| changeToInitialAmountAsOfRoundZero = zero, | ||
| changeToHoldingFeesRate = zero, | ||
| cumulativeChangeToInitialAmountAsOfRoundZero = zero, | ||
| cumulativeChangeToHoldingFeesRate = zero, | ||
| totalAmuletBalance = zero, | ||
| ), | ||
| roundPartyTotals = mkRoundAggregateWithoutDecoder().roundPartyTotals.map( | ||
| _.copy( | ||
| cumulativeChangeToInitialAmountAsOfRoundZero = zero, | ||
| cumulativeChangeToHoldingFeesRate = zero, | ||
| ) | ||
| ), | ||
| ) | ||
|
|
||
| def getConnections(roundAggregateResponse: () => RoundAggregate) = { | ||
| val connections = getMockedConnections(n = 10) | ||
| connections.foreach { mock => | ||
| when(mock.getAggregatedRounds()) | ||
| .thenReturn(Future.successful(Some(RoundRange(round, round)))) | ||
| when(mock.getRoundAggregate(round)) | ||
| .thenReturn(Future.successful(Some(roundAggregateResponse()))) | ||
| } | ||
| connections | ||
| } | ||
|
|
||
| val bft = getBft(getConnections(() => mkRoundAggregateUsingDecoder())) | ||
| val con = | ||
| new ScanAggregatesConnection(bft, retryProvider, retryProvider.loggerFactory) | ||
| val result = con.getRoundAggregate(round).futureValue | ||
| result shouldBe Some(roundAggregateZeroBalanceValues) | ||
|
|
||
| // not using the decoder should fail on the randomized balance values. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why even test/commit this? That's a code path that doesn't exist like this anymore, isn't it?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to be sure the decode stuff does something
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well if it didn't the previous
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah true, I could remove it, but liked to see it was failing the consensus, so I didn't do some encode/decode that did nothing
OriolMunoz-da marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| val bftFail = getBft(getConnections(() => mkRoundAggregateWithoutDecoder())) | ||
| val conFail = | ||
| new ScanAggregatesConnection(bftFail, retryProvider, retryProvider.loggerFactory) | ||
| val resultFail = conFail.getRoundAggregate(round).failed.futureValue | ||
| resultFail shouldBe an[BftScanConnection.ConsensusNotReached] | ||
| } | ||
|
|
||
| "Not get round aggregates from scans that report having the round aggregate if too many fail" in { | ||
| val connections = getMockedConnections(n = 10) | ||
| connections.zipWithIndex.foreach { case (mock, index) => | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.