replayprotection.sol
Overview
This Solidity source file implements an abstract contract ReplayProtection that provides a mechanism to prevent replay attacks on messages sent to the contract. Replay protection is essential in blockchain and distributed systems to ensure that a previously processed message cannot be maliciously or accidentally re-submitted and accepted again.
The contract maintains a record of processed messages indexed by their expiration timestamps and message hashes to detect duplicates. It also includes logic to periodically clean up expired entries to optimize storage.
Contract: ReplayProtection
Inheritance
Inherits from the
Errorscontract, which presumably defines custom error codes and messages used for require/assert statements.
Versioning
versionRP: A constant string"6.2.0"indicating the version of the replay protection implementation.
State Variables
Variable | Type | Description |
|---|---|---|
|
| Nested mapping to track processed messages by their expiration timestamp ( |
|
| Maximum iterations allowed when cleaning up expired messages to avoid gas exhaustion. |
|
| Struct holding the information about the last processed message, specifically its hash and expiration timestamp. |
|
| Dummy variable demonstrating contract functionality (unused in core logic). |
Modifiers
saveMsg: Calls the internal function_saveMsg()to record the current message as processed, then commits the state changes withtvm.commit(). It is intended to be used on functions handling messages requiring replay protection.
Internal Functions
_saveMsg()
Visibility: internal
Behavior: Marks the last message hash and expiration timestamp as processed in the
messagesmapping.Algorithm:
Calls the
gc()function to clean expired entries before saving the new message.Sets
messages[lastMessage.expireAt][lastMessage.messageHash] = true.
Usage: Called automatically by the
saveMsgmodifier to persist message processing.
afterSignatureCheck(TvmSlice body, TvmCell message)
Visibility:
privateInline: Yes
Parameters:
body:TvmSlicecontaining the message payload to be processed.message:TvmCellrepresenting the entire original message.
Returns:
TvmSlice— the remainder of the message body after reading header fields.Description:
This function is invoked automatically by the TVM (TON Virtual Machine) as a hook to perform custom replay protection after the message signature has been verified.
Reads and validates the expiration timestamp (
expireAt) embedded in the message.Ensures that:
The expiration timestamp is strictly greater than the current block timestamp (block.timestamp).
The expiration timestamp is not more than 5 minutes in the future to prevent long-lived messages.
Computes the hash of the entire message (messageHash).
Checks if this message hash for the given expiration has already been processed (replay detection).
Throws errors using custom error codes if any validation fails.
Stores the current message info (
lastMessage) for later saving.Returns the remainder of the message body slice so further processing can continue.
Usage: This method replaces the default replay protection mechanism with a custom one.
gc()
Visibility:
privateDescription:
Garbage collector function that deletes expired entries from the
messagesmapping.Iterates over stored expiration timestamps and deletes those that are older or equal to the current block.timestamp.
Limits the number of deletions per call to
MAX_CLEANUP_ITERATIONS(20) to control gas usage.Stops early if it encounters a non-expired message timestamp (since entries are assumed to be ordered).
Implementation Notes:
The semicolon after
mis used to avoid compiler warnings about unused variables.Uses a
for-loop with tuple deconstruction to iterate mappings.
Data Structures
MessageInfo (Imported)
A struct imported from "./structs/structs.sol" presumably containing at least:
messageHash (likely uint256 or similar)
expireAt(uint32)
This struct holds the essential metadata for replay protection checks.
Error Handling
Inherits error definitions from the
Errorscontract (./errors.sol).Uses specific error codes such as:
ERR_MESSAGE_EXPIRED: Message expired.
ERR_MESSAGE_WITH_HUGE_EXPIREAT: Expiration timestamp too far in the future.
ERR_MESSAGE_IS_EXIST: Message already processed (replay detected).
ERR_NOT_OWNER: (Commented out modifier usage) Owner check failure.
Interaction with Other Parts of the System
Imports
ErrorsandMessageInfostruct from errors.sol and structs/structs.sol respectively.Uses tvm built-in functions and types:
tvm.accept(),
tvm.commit(): Transaction lifecycle control.tvm.hash(message): Hashing the message for uniqueness checks.
The contract is abstract, intended to be inherited by other contracts that require replay protection.
The
afterSignatureCheckfunction is a predefined hook in the TVM that replaces the default replay protection with this custom implementation.The
saveMsgmodifier should be applied to functions processing messages to ensure replay protection state is updated.
Usage Example
contract MyContract is ReplayProtection {
function processMessage() public saveMsg {
// Message processing logic here
// The `saveMsg` modifier ensures replay protection is applied
}
}
Important Implementation Details and Algorithms
Replay Protection via Expiration + Hashing:
Each message must contain an expiration timestamp.
The combination of
expireAtand message hash uniquely identifies a message.Once stored, any duplicate message with the same
expireAtand hash will be rejected.
Cleanup Algorithm:
The
gc()method ensures that messages with expired timestamps are removed to limit state growth.The cleanup is bounded by a maximum number of iterations to prevent excessive gas consumption.
The method assumes the mapping keys (
expireAt) are iterated in ascending order (or at least grouped by expiry time).
Replay Protection Hook:
The
afterSignatureCheckspecial function is a mechanism of the underlying platform (TVM) to insert custom logic after signature verification but before message execution.This allows fine-grained control over message acceptance and prevents replay attacks effectively.
Mermaid Class Diagram
classDiagram
class ReplayProtection {
+string versionRP
+mapping messages
+uint8 MAX_CLEANUP_ITERATIONS
+MessageInfo lastMessage
+uint __value
+modifier saveMsg()
-function _saveMsg()
-function afterSignatureCheck()
-function gc()
}
ReplayProtection --|> Errors
ReplayProtection o-- MessageInfo