Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion daml/dars.lock
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,15 @@ splice-dso-governance 0.1.21 2d306cfe8cdb3daf2d21f84dfecc3e2f26a41504e58fe25cb7f
splice-dso-governance 0.1.22 5c28530209b9ab37c5f187132cd826709bb18b0efe28411488ab750870414738
splice-dso-governance 0.1.23 0c94a036ac5168a1dee26b435838e062f0d2f47d6eac49303978228ae559edb9
splice-dso-governance 0.1.24 4974c654485d4ecaa6b5caf8ef3c2679efa8195c4b50d4965a8fff1b72e8efa4
splice-dso-governance 0.1.25 b41ffa8aadafc8ae78eeb39b201eca9bc96470267d36553badd5df2a0587b16f
splice-dso-governance 0.1.3 b0ae3cc03e418790305a3c15f761fe495572de5827f8d322fb8b96996b783c13
splice-dso-governance 0.1.4 dc24fd18b4d151cd1e0ff6bfb7438bafb2f50fe076d0f16f50565e60b153a0be
splice-dso-governance 0.1.5 9e3ca1d22ad495dfabf3d61acae3dc1a7718f527f02092280b58cf69edfdc84c
splice-dso-governance 0.1.6 4e7653cfbf7ca249de4507aca9cd3b91060e5489042a522c589d3c4199580cd8
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.30 13e5d00f8e2874f2d7480a1df1e622a97733dfa97406a9a04ff293823ab942b3
splice-dso-governance-test 0.1.31 96128520faebb74a7d11fcc80026d323d73e9d3c690e1b17f5cc86cd36e5e678
splice-token-standard-test 1.0.13 a556574314ab5ecbfa04b04a6b6c9259cf90388461fe307ba712257ad5993a6b
splice-token-test-dummy-holding 0.0.1 1cd171c6c42ab46dc9cf12d80c6111369e00cea5cdf054924b4f26ce94b1ef5b
splice-token-test-dummy-holding 0.0.2 4f40fb033ef3db89623642c1b494e846097fa32af138b3864a63aa15937a323d
Expand Down
Binary file added daml/dars/splice-dso-governance-0.1.25.dar
Binary file not shown.
2 changes: 1 addition & 1 deletion daml/splice-dso-governance-test/daml.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
sdk-version: 3.4.11
name: splice-dso-governance-test
source: daml
version: 0.1.30
version: 0.1.31
dependencies:
- daml-prim
- daml-stdlib
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,115 @@ import Splice.Testing.Utils
-- Vote Requests
----------------

-- | Tests the Phase 1 governance-voter action taxonomy.
testGovernanceVoterActionTaxonomy : Script ()
testGovernanceVoterActionTaxonomy = do
(_app, dso, (sv1, sv2, _sv3, _sv4)) <- initMainNet
provider <- allocateParty "taxonomy-provider"
beneficiary <- allocateParty "taxonomy-beneficiary"
newSv <- allocateParty "taxonomy-new-sv"
now <- getTime
[(_, dsoRules)] <- query @DsoRules dso
[(_, amuletRules)] <- query @AmuletRules dso
[(_, openRound), _, _] <- sortOn (._2.round) <$> query @OpenMiningRound dso
rightCid <- submit dso $ createCmd FeaturedAppRight with
dso
provider

forA_
[ ARC_DsoRules with
dsoAction = SRARC_GrantFeaturedAppRight DsoRules_GrantFeaturedAppRight with provider
, ARC_DsoRules with
dsoAction = SRARC_RevokeFeaturedAppRight DsoRules_RevokeFeaturedAppRight with rightCid
, ARC_DsoRules with
dsoAction = SRARC_SetConfig DsoRules_SetConfig with
newConfig = dsoRules.config
baseConfig = Some dsoRules.config
, ARC_DsoRules with
dsoAction = SRARC_UpdateSvRewardWeight DsoRules_UpdateSvRewardWeight with
svParty = sv1
newRewardWeight = 1
, ARC_DsoRules with
dsoAction = SRARC_CreateUnallocatedUnclaimedActivityRecord DsoRules_CreateUnallocatedUnclaimedActivityRecord with
beneficiary
amount = 1.0
reason = "taxonomy test"
expiresAt = now `addRelTime` (days 1)
, ARC_DsoRules with
dsoAction = SRARC_OffboardSv DsoRules_OffboardSv with sv = sv2
, ARC_AmuletRules with
amuletRulesAction = CRARC_SetConfig AmuletRules_SetConfig with
newConfig = amuletRules.configSchedule.initialValue
baseConfig = amuletRules.configSchedule.initialValue
]
(\action -> isGovernanceVoterAction action === True)

forA_
[ ARC_DsoRules with
dsoAction = SRARC_AddSv DsoRules_AddSv with
newSvParty = newSv
newSvName = "taxonomy-new-sv"
newSvRewardWeight = 1
newSvParticipantId = "taxonomy-participant"
joinedAsOfRound = openRound.round
, ARC_DsoRules with
dsoAction = SRARC_ConfirmSvOnboarding DsoRules_ConfirmSvOnboarding with
newSvParty = newSv
newSvName = "taxonomy-new-sv"
newParticipantId = "taxonomy-participant"
newSvRewardWeight = 1
reason = "taxonomy test"
, ARC_DsoRules with
dsoAction = SRARC_CreateExternalPartyAmuletRules DsoRules_CreateExternalPartyAmuletRules
, ARC_DsoRules with
dsoAction = SRARC_CreateTransferCommandCounter DsoRules_CreateTransferCommandCounter with
sender = provider
, ARC_DsoRules with
dsoAction = SRARC_CreateBootstrapExternalPartyConfigStateInstruction DsoRules_CreateBootstrapExternalPartyConfigStateInstruction
, ExtActionRequiringConformation with dummyUnitField = ()
]
(\action -> isGovernanceVoterAction action === False)

-- | Tests that vote updates keep one vote slot for the represented SV.
testVoteUpdateKeepsOneSlotPerSv : Script ()
testVoteUpdateKeepsOneSlotPerSv = do
(_app, dso, (sv1, sv2, _sv3, _sv4)) <- initMainNet
[(dsoRulesCid, _)] <- query @DsoRules dso

result <- submit (actAs sv1 <> readAs dso) $ exerciseCmd dsoRulesCid DsoRules_RequestVote with
requester = sv1
action = ARC_DsoRules with
dsoAction = SRARC_OffboardSv DsoRules_OffboardSv with
sv = sv2
reason = Reason with url = ""; body = "taxonomy tally test"
targetEffectiveAt = None
voteRequestTimeout = Some (days 7)
let initialRequestCid = result.voteRequest

Some initialRequest <- queryContractId dso initialRequestCid
Map.size initialRequest.votes === 1
case Map.lookup initialRequest.requester initialRequest.votes of
None -> fail "requester vote missing"
Some vote -> vote.sv === sv1

passTime (minutes 1)
result <- submit (actAs sv1 <> readAs dso) $ exerciseCmd dsoRulesCid DsoRules_CastVote with
requestCid = initialRequestCid
vote = Vote with
sv = sv1
accept = False
reason = Reason with url = ""; body = "updated vote"
optCastAt = None

Some updatedRequest <- queryContractId dso result.voteRequest
Map.size updatedRequest.votes === 1
updatedRequest.trackingCid === Some initialRequestCid
case Map.lookup updatedRequest.requester updatedRequest.votes of
None -> fail "updated requester vote missing"
Some vote -> do
vote.sv === sv1
vote.accept === False

-- | Tests vote request machinery on featured app right granting and revoking without effectivity.
testVoteRequestAcceptanceWithoutEffectivity : Script ()
testVoteRequestAcceptanceWithoutEffectivity = do
Expand Down
2 changes: 1 addition & 1 deletion daml/splice-dso-governance/daml.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
sdk-version: 3.4.11
name: splice-dso-governance
source: daml
version: 0.1.24
version: 0.1.25
dependencies:
- daml-prim
- daml-stdlib
Expand Down
20 changes: 20 additions & 0 deletions daml/splice-dso-governance/daml/Splice/DsoRules.daml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,26 @@ data AnsEntryContext_ActionRequiringConfirmation
-- ^ Automated action to reject initial payment of an ans entry.
deriving (Eq, Show)

-- | Phase 1 governance-voter action taxonomy.
--
-- This is deliberately an explicit allowlist. New action constructors are not
-- governance-voter eligible unless they are reviewed and added here.
isGovernanceVoterAction : ActionRequiringConfirmation -> Bool
isGovernanceVoterAction action = case action of
ARC_DsoRules with dsoAction -> case dsoAction of
SRARC_OffboardSv _ -> True
SRARC_GrantFeaturedAppRight _ -> True
SRARC_RevokeFeaturedAppRight _ -> True
SRARC_SetConfig _ -> True
SRARC_UpdateSvRewardWeight _ -> True
SRARC_CreateUnallocatedUnclaimedActivityRecord _ -> True
_ -> False
ARC_AmuletRules with amuletRulesAction -> case amuletRulesAction of
CRARC_SetConfig _ -> True
_ -> False
ARC_AnsEntryContext _ _ -> False
ExtActionRequiringConformation _ -> False

-- | Information about SVs relevant to DSO governance.
data SvInfo = SvInfo with
name : Text -- ^ Human-readable name; must be unique.
Expand Down
1 change: 1 addition & 0 deletions docs/src/sv_operator/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Supervalidators
sv_restore.rst
sv_security.rst
sv_operations.rst
sv_governance_voter.rst
sv_scratchnet.rst

.. todo:: Add sections top-level sections on upgrades, node onboarding, validator functionality, DR
Expand Down
24 changes: 24 additions & 0 deletions docs/src/sv_operator/sv_governance_voter.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
..
Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
..
SPDX-License-Identifier: Apache-2.0

SV Governance Voter Prototype
==============================

The governance-voter contract work is a prototype for review under
`Canton Development Fund PR #223 <https://github.com/canton-foundation/canton-dev-fund/pull/223>`_,
especially Milestone 1: Governance-Voting Identity and CIP.

Phase 1 preserves the current one-vote-per-SV model. A governance voter is
intended to be an alternate signer for the represented SV's vote on explicitly
supported non-operational governance actions; it is not a new voting unit and
does not add voting weight.

The first contract slice uses a hardcoded Daml allowlist for governance-voter
eligible actions. New ``ActionRequiringConfirmation`` constructors are rejected
by default until reviewed and added deliberately. The proposed allowlist is
intended to be concrete enough for maintainer and CIP review, not a final
statement of upstream governance policy. In particular, inclusion of
``SRARC_OffboardSv`` should be validated through that review because it is a
high-impact governance membership action.