---
id: TIP-1093
title: Extend Expiring Nonce Window to Five Minutes
description: Extends the expiring nonce validity window from 30 seconds to five minutes and resizes replay-protection storage accordingly.
authors: @shekhirin
status: Draft
related: TIP-1009, TIP-0001
protocolVersion: TBD
---

# TIP-1093: Extend Expiring Nonce Window to Five Minutes

## Abstract

This TIP extends the maximum validity window for expiring nonce transactions from
30 seconds to five minutes. It increases the circular replay-protection buffer
from 300,000 to 3,000,000 entries, preserving the TIP-1009 sizing target of
10,000 expiring-nonce transactions per second.

The storage layout and replay-protection algorithm remain unchanged. The larger
window gives applications more time between signing a transaction and submitting
it while retaining bounded replay-protection state.

## Motivation

Some use cases require more than 30 seconds between signing a transaction and
sending it. This can happen when a transaction is signed on a separate device,
passes through an approval workflow, or is queued by a relayer before it reaches
the network. A five-minute window supports these workflows without requiring
applications to re-sign transactions that are still intended to be valid.

TIP-1009 currently allows a maximum `validBefore` of 30 seconds and sizes its
replay-protection ring for 10,000 TPS over that interval. Keeping the existing
capacity while increasing the window would cause the ring to overwrite entries
that are still valid at the target throughput. This TIP therefore changes the
window and capacity together.

---

# Specification

## Expiry Window

For an expiring nonce transaction, `validBefore` MUST satisfy:

```text
now < validBefore <= now + 300
```

where `now` is the current block timestamp. Transactions with
`validBefore <= now` or `validBefore > now + 300` MUST be rejected during pool
validation and execution.

The transaction MUST continue to use `nonceKey = uint256.max`, `nonce = 0`, and
the TIP-1009 expiring nonce hash. No other nonce mode is changed by this TIP.

## Replay-Protection Capacity

The implementation constants become:

```text
EXPIRING_NONCE_MAX_EXPIRY_SECS = 300
EXPIRING_NONCE_SET_CAPACITY = 3_000_000
```

The capacity is calculated as:

```text
10,000 transactions/second × 300 seconds = 3,000,000 entries
```

The `expiringNonceRing` mapping continues to store one 32-byte transaction hash
per entry. Including MPT node overhead, MDBX metadata, and RLP encoding, each
live expiring-nonce entry uses approximately 107 bytes, or 321 MB at full
capacity. This estimate is based on the controlled 100,000-transaction benchmark
at 5,000 TPS in
[TIP-1009](https://tips.sh/1009?h=8965-8968#controlled-benchmark-100k-transactions-at-5k-tps)

The ring pointer remains bounded to `[0, EXPIRING_NONCE_SET_CAPACITY)` and wraps
to zero after entry `2,999,999`. Before overwriting an occupied ring entry, the
implementation MUST read the old hash's expiry and reject with
`ExpiringNonceSetFull` if that expiry is still in the future. Otherwise it MUST
clear the old `expiringNonceSeen` entry and insert the new hash and expiry.

## Activation and Compatibility

The new constants MUST activate atomically at the protocol version selected for
this TIP. Pool validation, transaction execution, action replay, transaction
builders, and test helpers MUST use the same 300-second maximum.

At the activation boundary, transactions already recorded in the replay-
protection state remain recorded and cannot be replayed. The capacity extension
adds previously unallocated ring slots, so new post-activation transactions are
inserted into those slots rather than overwriting pre-activation entries. The
activation therefore does not create a replay window for transactions that were
accepted before the boundary.

Before activation, nodes continue enforcing the TIP-1009 30-second limit. After
activation, nodes enforcing different limits or capacities MUST be treated as
incompatible and MUST NOT participate in the same canonical chain.