diff --git a/daml/dars.lock b/daml/dars.lock index 5d0ec1c0c0..f120105cf4 100644 --- a/daml/dars.lock +++ b/daml/dars.lock @@ -97,7 +97,7 @@ splice-dso-governance 0.1.6 4e7653cfbf7ca249de4507aca9cd3b91060e5489042a522c589d splice-dso-governance 0.1.7 d406eba1132d464605f4dae3edf8cf5ecbbb34bd8edef0e047e7e526d328718c splice-dso-governance 0.1.8 1790a114f83d5f290261fae1e7e46fba75a861a3dd603c6b4ef6b67b49053948 splice-dso-governance 0.1.9 9ee83bfd872f91e659b8a8439c5b4eaf240bcf6f19698f884d7d7993ab48c401 -splice-dso-governance-test 0.1.35 70ce02d6a76a5c4028697e709ee27ea8a12f733e69c14d5c8f0b30a81b98307c +splice-dso-governance-test 0.1.35 7473784b718b4fe2ea11a12b3a72ad4fffa961d0bcd0948b3c528a5491e69fcd splice-test-token-v1 1.0.0 aaa0b576b5a3db49b3a4f7a4710fe6f8ae462aabbde4da89f639eb87fd62e90c splice-test-token-v1-test 1.0.2 6d98651845b29da33f75e9f0c8e76a36a1e46d8351e58d86d6ba4ba915566427 splice-test-token-v2 1.0.0 a38a96b6f46c14c599b2763bc4fc68911a9cada90f89c599a1401e8e3df685e1 diff --git a/daml/splice-dso-governance-test/daml/Splice/Scripts/DsoTestUtils.daml b/daml/splice-dso-governance-test/daml/Splice/Scripts/DsoTestUtils.daml index 4878af09b2..0ddb03f191 100644 --- a/daml/splice-dso-governance-test/daml/Splice/Scripts/DsoTestUtils.daml +++ b/daml/splice-dso-governance-test/daml/Splice/Scripts/DsoTestUtils.daml @@ -12,6 +12,7 @@ import qualified DA.Map as Map import DA.Optional (fromOptional) import qualified DA.Set as Set import qualified DA.Text as T +import qualified DA.TextMap as TextMap import Daml.Script import DA.Time @@ -25,7 +26,7 @@ import Splice.ValidatorLicense import Splice.Scripts.Util import Splice.Testing.Registries.AmuletRegistry.Parameters -import Splice.Testing.Registries.AmuletRegistry (advanceToNextRoundChange) +import Splice.Testing.Registries.AmuletRegistry (advanceToNextRoundChange, getActiveOpenRoundsSorted) import Splice.CometBft import Splice.DsoRules @@ -160,6 +161,25 @@ initDecentralizedSynchronizerWithAmuletPrice isDevNet initialRound amuletPrice o pure (app, dso, (sv1, sv2, sv3, sv4)) +-- | The reward state of the SV node operator with the given name. +getSvRewardStateCid : AmuletApp -> Text -> Script (ContractId SvRewardState) +getSvRewardStateCid app svName = do + [(rewardStateCid, _)] <- queryFilter @SvRewardState app.dso (\state -> state.svName == svName) + pure rewardStateCid + +-- | The reward states of all SV node operators, keyed by the operator's name. +getSvOperatorRewardStateCids : AmuletApp -> Script (TextMap.TextMap (ContractId SvRewardState)) +getSvOperatorRewardStateCids app = do + [(_, rules)] <- query @DsoRules app.dso + fmap TextMap.fromList $ forA (Map.values rules.svs) $ \info -> do + rewardStateCid <- getSvRewardStateCid app info.name + pure (info.name, rewardStateCid) + +getOpenMiningRoundTriple : AmuletApp -> Script OpenMiningRoundTriple +getOpenMiningRoundTriple app = do + [(round0Cid, _), (round1Cid, _), (round2Cid, _)] <- getActiveOpenRoundsSorted app.dso + pure OpenMiningRoundTriple with round0Cid; round1Cid; round2Cid + getSvInfoByParty : AmuletApp -> Party -> Script SvInfo getSvInfoByParty app sv = do [(_, rules)] <- query @DsoRules app.dso diff --git a/daml/splice-dso-governance-test/daml/Splice/Scripts/TestSvRightOwners.daml b/daml/splice-dso-governance-test/daml/Splice/Scripts/TestSvRightOwners.daml new file mode 100644 index 0000000000..76529dbbb4 --- /dev/null +++ b/daml/splice-dso-governance-test/daml/Splice/Scripts/TestSvRightOwners.daml @@ -0,0 +1,79 @@ +-- Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +-- SPDX-License-Identifier: Apache-2.0 + +module Splice.Scripts.TestSvRightOwners where + +import DA.Assert +import qualified DA.Map as Map +import qualified DA.Set as Set +import qualified DA.TextMap as TextMap +import DA.Time + +import Daml.Script + +import Splice.Amulet.SvRightOwner +import Splice.DsoRules +import Splice.Scripts.DsoTestUtils +import Splice.Scripts.Util + +-- | Migrate the SV node operators of the test network to SV right owners of the same name. +test_MigrateToOnLedgerSvRightOwners : Script () +test_MigrateToOnLedgerSvRightOwners = do + (app, dso, (sv1, sv2, sv3, sv4)) <- initMainNet + svRightOwners <- svRightOwnerInfosFromOperators app + + initiateAndAcceptVote app [sv1, sv2, sv3, sv4] $ ARC_DsoRules with + dsoAction = SRARC_MigrateToOnLedgerSvRightOwners DsoRules_MigrateToOnLedgerSvRightOwners with + svRightOwners + + [(instructionCid, _)] <- query @MigrateToOnLedgerSvRightOwnersInstruction dso + openMiningRoundTriple <- getOpenMiningRoundTriple app + svOperatorRewardStateCids <- getSvOperatorRewardStateCids app + svSubmits app sv1 $ \dsoRulesCid -> + exerciseCmd dsoRulesCid DsoRules_ExecuteMigrateToOnLedgerSvRightOwnersInstruction with + instructionCid + openMiningRoundTriple + svOperatorRewardStateCids + svOperator = sv1 + + [(_, dsoRules)] <- query @DsoRules dso + [info.svRewardWeight | info <- Map.values dsoRules.svs] === [0, 0, 0, 0] + dsoRules.svRightOwners === Some (Set.fromList ["sv1", "sv2", "sv3", "sv4"]) + + owners <- query @SvRightOwner dso + TextMap.fromList [(owner.name, owner.info) | (_, owner) <- owners] === svRightOwners + +test_ExpireMigrateToOnLedgerSvRightOwnersInstruction : Script () +test_ExpireMigrateToOnLedgerSvRightOwnersInstruction = do + (app, dso, (sv1, sv2, sv3, sv4)) <- initMainNet + svRightOwners <- svRightOwnerInfosFromOperators app + + initiateAndAcceptVote app [sv1, sv2, sv3, sv4] $ ARC_DsoRules with + dsoAction = SRARC_MigrateToOnLedgerSvRightOwners DsoRules_MigrateToOnLedgerSvRightOwners with + svRightOwners + + [(instructionCid, _)] <- query @MigrateToOnLedgerSvRightOwnersInstruction dso + passTime (hours 2) + svSubmits app sv1 $ \dsoRulesCid -> + exerciseCmd dsoRulesCid DsoRules_ExpireMigrateToOnLedgerSvRightOwnersInstruction with + instructionCid + svOperator = sv1 + + [] <- query @MigrateToOnLedgerSvRightOwnersInstruction dso + pure () + +mkSvRightOwnerInfo : Party -> Int -> Text -> SvRightOwnerInfo +mkSvRightOwnerInfo rightOwner weight operatorName = SvRightOwnerInfo with + rightOwnerParty = rightOwner + rewardWeight = weight + rewardNodeOperatorName = operatorName + beneficiaries = Map.empty + +-- | The SV node operators as SV right owners of their own name, preserving the total weight. +svRightOwnerInfosFromOperators : AmuletApp -> Script (TextMap.TextMap SvRightOwnerInfo) +svRightOwnerInfosFromOperators app = do + [(_, dsoRules)] <- query @DsoRules app.dso + pure $ TextMap.fromList + [ (info.name, mkSvRightOwnerInfo party info.svRewardWeight info.name) + | (party, info) <- Map.toList dsoRules.svs + ]