> ## Documentation Index
> Fetch the complete documentation index at: https://docs.optimism.io/llms.txt
> Use this file to discover all available pages before exploring further.

# OP Stack의 Subblocks와 gas 사용량

> Subblocks가 블록 gas 사용량과 트랜잭션 포함에 어떤 영향을 미치는지, 그리고 대용량 트랜잭션이 거부되거나 pending 상태로 남을 수 있는 이유를 설명합니다.

이 문서에서는 **subblocks**가 블록 gas 사용량, 트랜잭션 포함, 대용량 트랜잭션 처리에 어떤 영향을 미치는지, 그리고 예기치 않은 트랜잭션 거부를 피하는 방법을 설명합니다.

subblocks에 익숙하지 않다면 [Subblocks 설명](https://docs.optimism.io/ko/op-stack/features/subblocks.md)에서 자세히 알아볼 수 있습니다.

***

## 배경: 블록 gas 한도와 트랜잭션 gas 한도

OP Mainnet에서 **이론적인 블록 gas 한도**는 현재 **40M gas**입니다. 기존 EVM의 사고방식에서는 단일 트랜잭션이 블록 gas 한도를 초과하지 않는 한 전체 블록 gas 한도까지 사용할 수 있습니다.

**subblocks**에서는 블록이 점진적으로 구성되며, *실제 트랜잭션 포함 여부는 이론적인 최댓값뿐만 아니라 블록 내에서 이미 소비된 gas에 따라 달라집니다*.

***

## Subblocks란 무엇인가요?

Subblocks는 점진적인 블록 생성 메커니즘입니다. sequencer의 실행 클라이언트는 전체 블록을 한 번에 구성하는 대신 일련의 subblock으로 블록을 조립하며, 각 subblock은 포함에 사용할 수 있는 *누적 gas 예산*을 늘립니다.
subblocks가 무엇이며 블록의 subblock 수가 어떻게 결정되는지는 [Subblocks 설명](https://docs.optimism.io/ko/op-stack/features/subblocks.md)을 참조하세요.
gas 사용량 측면에서의 결과는, 앞쪽 subblock에는 작은 트랜잭션만 포함될 수 있고 큰 트랜잭션은 *충분한 gas가 남아 있는 경우에만* 블록의 뒤쪽에 들어갈 수 있다는 것입니다.

### 예시

다음과 같이 가정합니다.

* 블록 gas 한도 **B = 40M**
* subblock 수 **N = 10**(2초 블록 시간과 200 ms 간격에서 도출되는 수)

그러면 누적 gas 한도는 다음과 같이 증가합니다.

| Subblock | 사용 가능한 최대 누적 gas |
| - | - |
| 1 | 4M |
| 2 | 8M |
| 3 | 12M |
| 4 | 16M |
| 5 | 20M |
| 6 | 24M |
| 7 | 28M |
| 8 | 32M |
| 9 | 36M |
| 10 | 40M |

**20M gas 한도**를 가진 트랜잭션은 subblock 5부터 포함될 수 있으며, *이전 subblock들이 해당 gas를 이미 소비하지 않은 경우에만* 포함될 수 있습니다.

subblock 수는 고정되어 있지 않습니다. 한 간격에서 실행 부하가 크면 이후 간격에 남는 시간이 줄어들므로, 실제 블록에는 간격에서 도출되는 수보다 적은 subblock이 포함될 수 있습니다.

***

## 트랜잭션이 멈출 수 있는 이유

트랜잭션이 전체 블록 gas 한도보다 낮은 gas 한도(예: **38M \< 40M**)로 제출되었더라도 pending 상태로 남거나, EL 구현에 따라 `exceeds block gas limit` 오류와 함께 거부될 수 있습니다.

이는 트랜잭션 수락과 트랜잭션 포함이 서로 다른 구성 요소에 의해 결정되기 때문입니다.

일반적으로 다음과 같습니다.

* 들어오는 트랜잭션은 먼저 Execution Layer txpool에 들어갑니다.
* EL은 `tx.gasLimit`이 **전체 블록 gas 한도**를 초과하는지 확인합니다.
  * 초과하면 `exceeds block gas limit`과 함께 거부합니다.
  * 그렇지 않으면 트랜잭션을 **pending/queued mempool**에 보관하고 **P2P gossip**으로 전파하여 결국 **sequencer**에 도달하게 합니다.
* **sequencer의 실행 클라이언트**는 점진적인 **남은 블록 gas** 검사를 적용하여 해당 트랜잭션을 subblock에 포함할지, pending 상태로 둘지 결정합니다.

### 실제 사례

* 블록 gas 한도: **40M**
* 이전 subblock에서 이미 사용된 gas: **13M**
* 남은 gas: **27M**
* 들어오는 트랜잭션의 gas 한도: **38M**

**EL**은 트랜잭션이 **40M**을 초과하는지 확인합니다. **38M \< 40M**이므로 트랜잭션은 pending/queued mempool에 수락되고 **sequencer**로 gossip됩니다.
sequencer의 실행 클라이언트는 점진적인 남은 gas 제약 조건을 적용합니다. 남은 gas가 **27M**뿐이고 트랜잭션에는 **38M**이 필요하므로 트랜잭션은 아직 포함될 수 없으며 pending 상태로 남습니다.

**결과:** 트랜잭션은 거부되지 않지만, subblock에 포함될 만큼 충분한 gas가 남을 때까지 mempool에서 pending 상태로 남습니다.

***

## 클라이언트 동작 및 오류 메시지

트랜잭션 크기에 따라 두 가지 다른 결과가 발생합니다.

* **즉시 거부(txpool 수락 실패):**\
  EL(예: **op-reth**)은 트랜잭션 gas 한도가 **전체 블록 gas 한도**를 초과하는 경우에만 트랜잭션을 거부합니다.
  * 조건: `tx.gasLimit > blockGasLimit`
  * 사용자에게 반환되는 오류: `exceeds block gas limit`

* **수락되었지만 포함 대기 중:**\
  트랜잭션 gas 한도가 블록 gas 한도 **이내**이지만, 블록의 해당 시점에서 **남은 블록 gas**에 들어가기에는 여전히 너무 큰 경우 아직 포함되지 않습니다.
  * 트랜잭션은 **pending/queued mempool**에 남아 이후 subblock에서 충분한 gas가 확보되기를 기다립니다.
  * 사용자 관점에서는 포함에 필요한 gas가 확보될 때까지 트랜잭션이 **pending** 상태로 보일 수 있습니다.

실제로 트랜잭션은 Execution Layer RPC node로(예: proxyd를 통해) 전송되어 검사를 받으며, EL txpool에 수락된 경우에만 최종적으로 sequencer로 전파되어 포함될 수 있습니다.

txpool 재브로드캐스트와 같은 메커니즘을 구현하면 이러한 차이를 자동으로 완화하여 사용자가 재시도를 인지하지 못하게 할 수 있습니다. 다만 오류가 표시되는 경우, 해당 오류는 수신(ingress) 클라이언트의 gas 검사에서 발생한 것일 수 있습니다.

***

## 애플리케이션 개발자와 최종 사용자를 위한 실용 가이드

### 대용량 트랜잭션에는 여유분 남기기

대용량 트랜잭션을 제출하는 경우 전체 블록 gas 한도를 목표로 하지 마세요.

**권장 방법:**

* 블록 gas 한도 대비 **20\~30%의 여유분**을 남기세요
* 40M 블록의 경우 **28\~32M gas** 이하를 목표로 하세요

또는:

* 향후 도입될 L2 Fusaka 트랜잭션 한도에 맞추어 단일 트랜잭션 gas 사용량을 약 16.7M gas로 미리 제한하세요

이렇게 하면 블록이 부분적으로 사용된 상황에서도 트랜잭션이 Execution Layer gas 검사를 통과할 가능성이 높아집니다.

더 일반적으로, 예정된 프로토콜 변경(L2의 Fusaka)으로 인해 어차피 트랜잭션이 16.7M gas로 제한될 것이므로, 지나치게 큰 단일 트랜잭션을 피하도록 애플리케이션을 설계하는 것이 장기적으로 좋은 관행입니다.

***

### 혼잡 시 가용 gas가 달라질 수 있음을 예상하기

수요가 높은 상황에서는 다음과 같은 일이 발생합니다.

* 앞쪽 subblock이 가득 차는 경우가 많습니다
* 블록 뒤쪽의 남은 gas가 제한될 수 있습니다
* 매우 큰 트랜잭션은 거부되거나 재시도가 필요할 수 있습니다

이는 subblocks에서 예상되는 동작이며, 반드시 트랜잭션 자체의 문제는 아닙니다.

***

### 트랜잭션 재제출

블록 상태는 빠르게 변하므로 다음 사항에 유의하세요.

* 이후 블록에서 제출을 다시 시도하면 성공할 수 있습니다
* 대용량 트랜잭션은 앞쪽 subblock이 덜 혼잡할 때 포함될 가능성이 더 높습니다

***

## 핵심 요약

* Subblocks는 블록을 점진적으로 생성하며, gas 용량을 한 번에 모두 여는 대신 시간에 따라 단계적으로 엽니다\
  *(예: subblock이 10개인 40M gas 블록에서는 첫 번째 subblock에서 4M만 사용할 수 있고, 그다음 8M, 이런 식으로 증가합니다)*

* 트랜잭션이 EL txpool에 수락되려면 **전체 블록 gas 한도 이내**여야 하지만, sequencer가 다음 subblock에 포함하려면 **남은 블록 gas** 안에 들어가야 합니다
  *(예: 40M 중 13M gas가 이미 사용되었다면, 38M gas 트랜잭션은 EL에 수락될 수 있지만 sequencer에 도달한 후 충분한 gas가 남을 때까지 포함될 수 없습니다)*

* 그 결과, 대용량 트랜잭션은 gas 한도가 명목상의 블록 한도보다 낮더라도 **수락되었지만 pending 상태로 남을** 수 있습니다\
  *(예: 38M gas 트랜잭션은 40M gas 블록에서 수락될 수 있지만 활동이 많은 기간에는 지연될 수 있습니다)*

* 의미 있는 여유분을 남기는 것이 대용량 트랜잭션의 포함 성공률을 높이는 가장 확실한 방법입니다\
  *(예: 전체 40M 대신 28\~32M gas를 목표로 하거나, 16.7M gas라는 Fusaka 한도를 미리 적용하세요)*
