Skip to content

Reward factor state machine - #6

Open
jonored wants to merge 2 commits into
jg/cip-0105-externally-implemented-governance-locksfrom
sv-weight-adjustment-poc
Open

Reward factor state machine#6
jonored wants to merge 2 commits into
jg/cip-0105-externally-implemented-governance-locksfrom
sv-weight-adjustment-poc

Conversation

@jonored

@jonored jonored commented Aug 3, 2026

Copy link
Copy Markdown

Does not yet include fixing the tests.

Pull Request Checklist

Cluster Testing

  • If a cluster test is required, comment /cluster_test on this PR to request it, and ping someone with access to the DA-internal system to approve it.
  • If an upgrade test is required, comment /upgrade_test on this PR to request it, and ping someone with access to the DA-internal system to approve it.
  • If a hard-migration test is required (from the latest release), comment /hdm_test on this PR to request it, and ping someone with access to the DA-internal system to approve it.
  • If a logical synchronizer upgrade test is required (from canton-3.5), comment /lsu_test on this PR to request it, and ping someone with access to the DA-internal system to approve it.

PR Guidelines

  • Include any change that might be observable by our partners or affect their deployment in the release notes.
  • Specify fixed issues with Fixes #n, and mention issues worked on using #n
  • Include a screenshot for frontend-related PRs - see README or use your favorite screenshot tool

Merge Guidelines

  • Make the git commit message look sensible when squash-merging on GitHub (most likely: just copy your PR description).

Does not include fixing the tests.

@meiersi-da meiersi-da left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Very valuable to have this code to align on the implementation. Directionally this seems right, but it looks like the logic might be simplified.

Comment thread daml/splice-dso-governance/daml/Splice/DSO/SvRightOwner.daml Outdated
-- ^ the weight of an SV for voting, can be zero
rewardWeight : Int
-- ^ the weight of an SV for reward minting, can be zero
rewardFactorState: Optional SvRightOwnerRewardFactorState

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
rewardFactorState: Optional SvRightOwnerRewardFactorState
rewardAdjustmentState: Optional RewardAdjustmentState

Comment on lines +39 to +40
permanentWeightFactor : Decimal
-- ^ the permanent maximum weight factor due to permanent underlocking

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have expected that we don't store that here at all. Instead just adjust the SvRightOwner.rewardWeight directly.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wary of not storing this or a copy of the original rewardWeight, because we need to not apply a loss factor repeatedly and the degree of underlocked an SV is does not change at all based on their weight; there's several wrong ways to do this where you can end up multiplying the rewardWeight by a factor repeatedly if we don't have the original number somewhere. The math is also a bit underspecified and if we treat permanent adjustments as updating the root truth, and can be complex just to keep avoiding repeated penalties.

Comment thread daml/splice-dso-governance/daml/Splice/DSO/SvRightOwner.daml Outdated
Comment thread daml/splice-dso-governance/daml/Splice/DSO/SvRightOwner.daml Outdated
effectiveTime : Time
controller dso
do
-- Assumes that we can calculate lock state one week in the past for enforcement.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

polish: push the core logic into Splice.DSO.SvState and add unit tests for it. Thereby improving readability and focus.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move is done, unit tests not yet.

permanentWeightFactor = 1.0
recoverableUnderlocks = []

let sevenDaysAgo = effectiveTime `addRelTime` days (-7)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

polish: make configurable

create svRightOwner with
info = svRightOwner.info with
rewardFactorState = Some currentRewardFactorState with
rewardWeightFactor = nextActive.newFactor

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment clarifying what None means? It presumably means "no adjustment". If that's the case though, then I'd expect that it resolves all underlocks and sets the rewardWeightFactor to 1.0?

Thinking about the logic a bit more it seems to me that there should be an implementation that works with just the new adjustment factor being passed in:
just remove all underlocks with adjustment factors <= the new adjustment factor.

I'd implement adjustment for

The under-locked portion of its SV Weight is removed from the active SV pool within 7 days
as part of reward coupon creation: retrieve the lowest adjustment factor older than 7 days.

The above are just sketches of parts of the full implementation. It does though hint at options to simplify the algorithm. My suspicion is that it should only need the earliest time at which a non-recovered underlock occurred. So a Map Decimal Time might be the right type to drive the logic.

That said: I might well be misunderstanding the problem. Probably best to do a code walkthrough together this afternoon.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably is clearer to just split the None case off into it's own choice or remove the need for it entirely; it's "update the active adjustment to the most recent underlock more than seven days before effectiveTime". It's certainly an option to just not store the "current" value and seek to it for each reward, there was just a stated preference at one point for explicit management of the weight.

Comment thread daml/splice-dso-governance/daml/Splice/DsoRules.daml Outdated
Comment thread daml/splice-dso-governance/daml/Splice/DsoRules.daml Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants