Skip to main content

OffsettingRateLimiter

Git Source

Inherits: IOffsettingRateLimiter

Title: OffsettingRateLimiter

An abstract rate limiter that maintains independent outbound and inbound rate limits per endpoint, and offsets activity in one direction against the in-flight amount of the other.

Each endpoint has two rate limits: outbound (outRateLimits) and inbound (inRateLimits), whose in-flight amounts decay linearly over the configured window. A flow debits its own side in full and offsets the counterpart by reducing its in-flight with a floor at zero; excess credit is dropped, not carried over.

This is not net accounting: the trailing leg of a round trip always records its full amount, since the leading leg's in-flight has already partially decayed by the time it is cancelled. A balanced round trip therefore leaves residual in-flight equal to the trailing leg, not zero.

Only internal mutators are exposed; an inheriting contract must gate configuration and reset behind its own access control and invoke _outflow / _inflow from the appropriate code paths.

State Variables​

outRateLimits​

Returns the stored outbound rate limit state for a destination endpoint.

The returned inFlight value is the raw stored amount and has not been decayed against the current timestamp. Callers that require the current effective capacity should use sendable instead.

mapping(uint32 dstEid_ => RateLimit) public override outRateLimits;

Parameters

NameTypeDescription
dstEid_uint32The destination endpoint identifier.

Returns

NameTypeDescription
inFlightuint256The stored in-flight amount.
limituint256The maximum amount that may be in flight at any point.
windowuint32The length in seconds of the sliding window.
lastUpdateduint48The timestamp of the most recent update.

inRateLimits​

Returns the stored inbound rate limit state for a source endpoint.

The returned inFlight value is the raw stored amount and has not been decayed against the current timestamp. Callers that require the current effective capacity should use receivable instead.

mapping(uint32 srcEid_ => RateLimit) public override inRateLimits;

Parameters

NameTypeDescription
srcEid_uint32The source endpoint identifier.

Returns

NameTypeDescription
inFlightuint256The stored in-flight amount.
limituint256The maximum amount that may be in flight at any point.
windowuint32The length in seconds of the sliding window.
lastUpdateduint48The timestamp of the most recent update.

Functions​

sendable​

Returns the current outbound capacity for a destination endpoint, with the in-flight amount decayed against the current timestamp.

When the configured window has fully elapsed since lastUpdated, or when the configured window is zero, the returned inFlight is zero and available is the full configured limit.

function sendable(
uint32 dstEid_
) external view virtual override returns (uint256 inFlight, uint256 available);

Parameters

NameTypeDescription
dstEid_uint32The destination endpoint identifier.

Returns

NameTypeDescription
inFlightuint256The decayed in-flight amount at the current timestamp.
availableuint256The amount that may still be sent before the rate limit is
exceeded.

receivable​

Returns the current inbound capacity for a source endpoint, with the in-flight amount decayed against the current timestamp.

When the configured window has fully elapsed since lastUpdated, or when the configured window is zero, the returned inFlight is zero and available is the full configured limit.

function receivable(
uint32 srcEid_
) external view virtual override returns (uint256 inFlight, uint256 available);

Parameters

NameTypeDescription
srcEid_uint32The source endpoint identifier.

Returns

NameTypeDescription
inFlightuint256The decayed in-flight amount at the current timestamp.
availableuint256The amount that may still be received before the rate limit
is exceeded.

_setOutRateLimits​

Configures the outbound rate limits for one or more destination endpoints.

For each configuration, the existing outbound rate limit is checkpointed against the current timestamp before the new limit and window values are written, so the stored in-flight amount continues to decay at the previous rate up to the moment of the change. The in-flight amount itself is preserved across the configuration change. The corresponding inbound rate limit is also checkpointed (decayed-in-place with lastUpdated refreshed) by the same call, but its limit and window are not modified. Repeated entries for the same endpoint within the same call are applied in order, so the last entry determines the final state. This deviates from the typical convention elsewhere in the codebase of reverting on duplicate inputs; here duplicates are accepted and the trailing entry overrides the earlier ones.

Emits an OutRateLimitsSet event.

function _setOutRateLimits(RateLimitConfig[] memory configs_) internal virtual;

Parameters

NameTypeDescription
configs_RateLimitConfig[]The outbound rate limit configurations to apply.

_setInRateLimits​

Configures the inbound rate limits for one or more source endpoints.

For each configuration, the existing inbound rate limit is checkpointed against the current timestamp before the new limit and window values are written, so the stored in-flight amount continues to decay at the previous rate up to the moment of the change. The in-flight amount itself is preserved across the configuration change. The corresponding outbound rate limit is also checkpointed (decayed-in-place with lastUpdated refreshed) by the same call, but its limit and window are not modified. Repeated entries for the same endpoint within the same call are applied in order, so the last entry determines the final state. This deviates from the typical convention elsewhere in the codebase of reverting on duplicate inputs; here duplicates are accepted and the trailing entry overrides the earlier ones.

Emits an InRateLimitsSet event.

function _setInRateLimits(RateLimitConfig[] memory configs_) internal virtual;

Parameters

NameTypeDescription
configs_RateLimitConfig[]The inbound rate limit configurations to apply.

_applyConfigs​

Applies a batch of rate limit configurations to a primary direction and checkpoints the in-flight amount against the previous configuration.

The function calls _settle with a zero delta for each entry, which decays the existing in-flight amount and refreshes lastUpdated to the current timestamp before the new limit and window are written. The counterpart rate limit is also checkpointed by the same call, since _settle always touches both sides, even though no delta is recorded.

function _applyConfigs(
mapping(uint32 => RateLimit) storage rlByEid_,
mapping(uint32 => RateLimit) storage counterpartRlByEid_,
RateLimitConfig[] memory configs_
) private;

Parameters

NameTypeDescription
rlByEid_mapping(uint32 => RateLimit)The mapping that holds the rate limits being configured.
counterpartRlByEid_mapping(uint32 => RateLimit)The mapping that holds the counterpart rate limits.
configs_RateLimitConfig[]The rate limit configurations to apply.

_clearOutboundInFlight​

Clears the outbound in-flight amount for one or more destination endpoints.

The in-flight amount is set to zero and lastUpdated is set to the current timestamp for each endpoint. The configured limit and window are not modified, and the corresponding inbound rate limits are not affected.

Emits an OutboundInFlightCleared event.

function _clearOutboundInFlight(uint32[] memory eids_) internal virtual;

Parameters

NameTypeDescription
eids_uint32[]The destination endpoint identifiers to reset.

_clearInboundInFlight​

Clears the inbound in-flight amount for one or more source endpoints.

The in-flight amount is set to zero and lastUpdated is set to the current timestamp for each endpoint. The configured limit and window are not modified, and the corresponding outbound rate limits are not affected.

Emits an InboundInFlightCleared event.

function _clearInboundInFlight(uint32[] memory eids_) internal virtual;

Parameters

NameTypeDescription
eids_uint32[]The source endpoint identifiers to reset.

_reset​

Clears the in-flight amount for a set of endpoints in the given mapping.

For each endpoint, the in-flight amount is set to zero and lastUpdated is set to the current timestamp. The limit and window are preserved.

function _reset(mapping(uint32 => RateLimit) storage rlByEid_, uint32[] memory eids_) private;

Parameters

NameTypeDescription
rlByEid_mapping(uint32 => RateLimit)The mapping that holds the rate limits to reset.
eids_uint32[]The endpoint identifiers to reset.

_outflow​

Records an outbound flow of amount_ to the destination endpoint and credits the inbound rate limit for the same endpoint by the same amount.

Reverts with RateLimitExceeded when amount_ is greater than the available outbound capacity at the current timestamp. The inbound credit is clamped at zero, so any excess credit beyond the inbound in-flight amount is dropped rather than carried over.

function _outflow(uint32 dstEid_, uint256 amount_) internal virtual;

Parameters

NameTypeDescription
dstEid_uint32The destination endpoint identifier.
amount_uint256The amount to record as an outbound flow.

_inflow​

Records an inbound flow of amount_ from the source endpoint and credits the outbound rate limit for the same endpoint by the same amount.

Reverts with RateLimitExceeded when amount_ is greater than the available inbound capacity at the current timestamp. The outbound credit is clamped at zero, so any excess credit beyond the outbound in-flight amount is dropped rather than carried over.

function _inflow(uint32 srcEid_, uint256 amount_) internal virtual;

Parameters

NameTypeDescription
srcEid_uint32The source endpoint identifier.
amount_uint256The amount to record as an inbound flow.

_currentState​

Computes the decayed in-flight amount and the remaining capacity of a rate limit at the current timestamp.

The decay is linear at a rate of limit_ / window_ per second from the stored inFlight_ value at lastUpdated_. When the elapsed time is at least window_, or when window_ is zero, the function returns a fully decayed result with inFlight equal to zero and available equal to the full limit_. The early return also avoids a division by zero when window_ is zero.

Integer division of decay rounds DOWN, so the effective inFlight is rounded UP and available is rounded DOWN relative to the exact linear curve. This is the protocol-favourable direction: a user can never observe more capacity than the true linear decay would grant, and any sub-quantum slack is held back rather than handed out early.

function _currentState(
uint256 inFlight_,
uint256 limit_,
uint32 window_,
uint48 lastUpdated_
) internal view virtual returns (uint256 inFlight, uint256 available);

Parameters

NameTypeDescription
inFlight_uint256The stored in-flight amount at the last update.
limit_uint256The maximum amount that may be in flight at any point.
window_uint32The length in seconds of the sliding window.
lastUpdated_uint48The timestamp of the most recent update.

Returns

NameTypeDescription
inFlightuint256The decayed in-flight amount at the current timestamp.
availableuint256The remaining capacity at the current timestamp.

_settle​

Settles a flow of delta_ against a primary rate limit and credits the counterpart rate limit by the same amount.

The function decays the primary rate limit, reverts with RateLimitExceeded when delta_ is greater than the remaining capacity, and otherwise stores the new in-flight value as the decayed amount plus delta_ and refreshes the primary lastUpdated to the current timestamp. The counterpart rate limit is then decayed and its in-flight value is reduced by delta_, with a floor at zero, after which its lastUpdated is also refreshed to the current timestamp.

When delta_ is zero, the call serves as a checkpoint that captures the current decayed in-flight amounts on both rate limits and refreshes the lastUpdated of both to the current timestamp without altering the effective remaining capacity.

function _settle(
RateLimit storage rl_,
RateLimit storage counterpartRl_,
uint256 delta_
) private;

Parameters

NameTypeDescription
rl_RateLimitThe storage reference to the primary rate limit (the one being debited by delta_).
counterpartRl_RateLimitThe storage reference to the counterpart rate limit (offset by delta_).
delta_uint256The amount to record on the primary side (and to be credited to the counterpart rate limit).

_subOrZero​

Returns a_ - b_ when a_ is greater than b_, and zero otherwise.

The subtraction is performed inside an unchecked block, since the conditional guarantees that no underflow can occur.

function _subOrZero(uint256 a_, uint256 b_) private pure returns (uint256);

Parameters

NameTypeDescription
a_uint256The minuend.
b_uint256The subtrahend.

Returns

NameTypeDescription
<none>uint256The non-negative difference, clamped at zero.