Skip to content

Conversation

ibrajer
Copy link
Contributor

@ibrajer ibrajer commented Sep 19, 2025

When setting a DON family active workflows limit, ensure that the default user limit is also configured. With a separate function, the contract admin can always override the default user limit, but never above the global DON family limit. The default user limit ensures fairness for all users who depend on having access to a chunk of a DON family capacity.

@ibrajer ibrajer self-assigned this Sep 19, 2025
Copy link
Contributor

github-actions bot commented Sep 19, 2025

Static analysis results are available

Hey @ibrajer, you can view Slither reports in the job summary here or download them as artifact here.
Please check them before merging and make sure you have addressed all issues.

@ibrajer ibrajer marked this pull request as ready for review September 19, 2025 19:01
@ibrajer ibrajer requested a review from a team as a code owner September 19, 2025 19:01
Comment on lines 1555 to 1560
// - if this user has no override, use the default user limit set for this DON
// - if this user has an override, use that unless it is bigger than the global cap set for this DON
uint32 cap = cfg.defaultUserLimit;
if (cfg.userOverride[owner].enabled) {
cap = cfg.userOverride[owner].value < cfg.limitValue.value ? cfg.userOverride[owner].value : cfg.limitValue.value;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

What if we want to intentionally limit some users below the don-user limit? A scenario here would be to limit users after pausing their workflows so they cannot reactivate them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, in that case, I think the only way to do that would be to explicitly set the user override to either zero (if we want to disallow deploying workflows completely) or set it to a much lower value than the current defaultUserLimit.

// It reverts with CallerIsNotWorkflowOwner
vm.prank(s_owner);
s_registry.setDONLimit(s_donFamily, 10, true);
s_registry.setDONLimit(s_donFamily, 100, 10);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit for future (don't change it now) - it helps to readability to have vars for these numbers, e.g., DON_WORKFLOWS_LIMIT and DEFAULT_USER_WORKFLOWS_LIMIT

DeividasK
DeividasK previously approved these changes Sep 24, 2025
eventType: EventType.DONCapacitySet,
timestamp: uint32(block.timestamp),
payload: abi.encode(donHash, newCapacity)
payload: abi.encode(donHash, donLimit)
Copy link
Contributor

@infiloop2 infiloop2 Sep 24, 2025

Choose a reason for hiding this comment

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

just verifying we don't need userDefaultLimit here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deividas said it's not needed in one of his previous comments so I removed it

Comment on lines 420 to 433
if (!ov.enabled) {
// → was OFF, now turning ON with new cap
// → was OFF, now turning ON with new the new limit override
ov.enabled = true;
ov.value = limit;
ov.value = userLimit;
s_donOverrideUsers[donHash].add(user);
emit UserDONLimitSet(user, donFamily, limit);
} else if (ov.value != limit) {
// → was ON with a different cap, so update it
ov.value = limit;
emit UserDONLimitSet(user, donFamily, limit);
emit UserDONLimitSet(user, donFamily, userLimit);
} else if (ov.value != userLimit) {
// → was ON with a different limit, so update it with a new override
ov.value = userLimit;
emit UserDONLimitSet(user, donFamily, userLimit);
} else {
// → already ON at exactly this cap, nothing to do
// → already ON at exactly this limit, nothing to do
return;
}
Copy link
Contributor

@infiloop2 infiloop2 Sep 24, 2025

Choose a reason for hiding this comment

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

nit. imo a lot of this logic can be simplified by simply doing

ov.enabled = true;
ov.value = userLimit;
emit UserDONLimitSet(user, donFamily, userLimit);

Copy link
Contributor

Choose a reason for hiding this comment

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

there's not much extra gas sent when value is written to the same value (if the storage slot doesn't change) and also prevents silent acknowledgement by the contract without any logs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've simplified it, please take a look

// Global limit must be explicitly enabled (zero or missing = disallowed)
if (!cfg.limitValue.enabled) revert DonLimitNotSet(donFamily);
// global limit must be explicitly enabled (zero means it is disabled)
if (cfg.limit == 0) revert DonLimitNotSet(donFamily);
Copy link
Contributor

Choose a reason for hiding this comment

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

just checking, is this function called when a workflow is deleted as well? in that case we would want to allow that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it is called on upsert, activate, activateBatch and updateDONFamily

infiloop2
infiloop2 previously approved these changes Sep 24, 2025
Copy link
Contributor

@infiloop2 infiloop2 left a comment

Choose a reason for hiding this comment

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

lgtm. added some small comments for improvements

@ibrajer ibrajer dismissed stale reviews from infiloop2 and DeividasK via 9d6bae5 September 25, 2025 08:33
@ibrajer ibrajer merged commit 9da00ca into develop Sep 25, 2025
51 checks passed
@ibrajer ibrajer deleted the feat/default-user-limits branch September 25, 2025 10:58
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.

3 participants