Lock
Relayers management can be tricky because of nonce management. The locking mechanisms available ensure conflict-free efficient access to the shared relayers without any invalid nonce issues.
Sharing mode
Depending on your infrastructure you may need to sync the relayers access & locking between different paymaster instances. The paymaster currently support 2 sharing mode:
Segregated
- If you have a single paymaster instance
The segregated lock system is an in-memory, single instance locking mechanism that uses standard Mutex protection with cooldown timers (to avoid invalid nonce). Whenever a thread needs a relayer to execute a transaction
- it acquires exclusive access to the list of relayers
- finds available relayers (enabled and not within cooldown period)
- chooses a random relayer from the list of available relayers
- creates a cooldown period (which is currently 5 seconds) starting from that instant ensuring that other threads dont use this relayer within this time
For unlocking a relayer after executing a transaction, the cooldown period is updated to the current instant and the nonce is updated for use in a subsequent transaction.
Shared
- If you have multiple paymaster instances accessing the same set of relayers
- Require a Redis configuration
The Redis locking system ensures that multiple paymaster instances can coordinate access to a set of shared relayer accounts without conflicts. It uses Redis as a distributed lock manager.
Internally, the paymaster uses keys of the form relayer-lock:{relayer_address_in_hex} to indicate a relayer is in use.
When the paymaster needs a relayer from amongst the shared relayers,
- it gets a connection to the configured redis instance
- gets the list of relayers
- gets the list of locked relayers
- finds the available relayers as the diff between list of relayers and locked relayers
- shuffles this list to avoid collisions when selecting relayers concurrently
- locks a relayer from this shuffled available list
- it then creates a lock for this relayer with the cached nonce if available
For unlocking a relayer after executing the transaction, the lock key mentioned earlier is deleted after updating the cached nonce for use in a subsequent transaction.
Scaling?You can learn more about scaling, and specifically horizontal scaling here
Relayers lock properties
Prop | Type | Description |
---|---|---|
relayers.lock.mode | "shared" | "seggregated" | How to manage relayers lock |
relayers.lock.redis.endpoint | string(url) | Redis endpoint. Only required if mode is "shared" |
relayers.lock.retry_timeout | number | Retry to acquire a relayer until the timeout in seconds is reached |
Example for Segregated Mode
{
"relayers": {
// ... other relayer properties
"lock": {
"retry_timeout": 1,
"mode": "seggregated"
},
// ... other relayer properties
},
}
Example for Shared Mode
{
"relayers": {
// ... other relayer properties
"lock": {
"mode": "shared",
"redis": {
"endpoint": "redis://127.0.0.1:6379"
}
},
// ... other relayer properties
},
}
Updated 12 days ago