Workspace IndexAlgorithms › Day 64

Sequencer Decentralization and Force Inclusion TODO

Algorithms · Day 64 / 100 · D. Distributed Systems & Consensus (Day 52-68)

Concept

Most rollups have a single entity operating the sequencer that orders transactions. This gives fast confirmation and low latency, but it leaves a censorship/liveness risk: if that entity excludes or halts a particular user's transactions, the user simply can't use the chain. Force inclusion sets a floor under that risk — if a user submits a transaction directly to an inbox contract on L1, bypassing the sequencer, the rollup must include it after a fixed delay window for the resulting state transition to be considered valid at all. That guarantees users at least an escape hatch, such as withdrawal, even if the sequencer censors them. Sequencer decentralization goes further, spreading the ordering authority itself across multiple parties — shared sequencers, stake-weighted rotation, or having the L1 proposer set order directly are all approaches being tried, each with different tradeoffs in latency, MEV, and complexity.

The worst-case scenario for any service deployed on an L2 is the sequencer halting or excluding just your transactions — and whether a force-inclusion path exists, and how long its delay window is, determines how long funds stay stuck when that happens. That's a practical criterion for choosing which chain to deploy on.

Code & Formula

# 시퀀서 분산화와 강제 포함(force inclusion) — 시퀀서가 검열해도 L1 inbox를 거치면 지연 창 이후 반드시 포함된다.
# 시퀀서가 특정 발신자를 계속 배제해도, 지연 창(DELAY)이 지난 forced tx는 다음 블록에 강제로 실린다.

DELAY = 3  # 강제 포함까지 걸리는 블록 수

class Sequencer:
    def __init__(self, censored_sender):
        self.censored_sender = censored_sender
        self.included = []

    def build_block(self, block_num, mempool, forced_inbox):
        already = {id(tx) for tx in self.included}
        # 강제 포함 마감이 지난 tx는 검열 여부와 무관하게 반드시 포함해야 유효한 블록이다
        due = [tx for tx in forced_inbox if block_num - tx["submitted_at"] >= DELAY and id(tx) not in already]
        censorable = [tx for tx in mempool if tx["sender"] != self.censored_sender and id(tx) not in already]
        block = due + [tx for tx in censorable if id(tx) not in {id(t) for t in due}]
        self.included.extend(block)
        return block

alice_tx = {"sender": "alice", "tx": "swap", "submitted_at": 0}
mempool = [alice_tx]
forced_inbox = [alice_tx]  # alice가 시퀀서 mempool과 L1 inbox에 동시 제출

seq = Sequencer(censored_sender="alice")
for block_num in range(6):
    block = seq.build_block(block_num, mempool, forced_inbox)
    status = [tx["sender"] for tx in block] if block else "(empty, 시퀀서가 검열 중)"
    print(f"블록 {block_num}: 포함된 tx = {status}")
    if block:
        break

print(f"\n시퀀서가 alice를 계속 배제했지만, 지연 창({DELAY}블록) 이후 강제 포함으로 결국 실렸다:", bool(seq.included))

Exercise

Find the force-inclusion (or forced-withdrawal) entry-point contract and its delay window in your L2's docs, then submit a forced-inclusion transaction through L1 yourself on testnet.

Practical Connection

Verex's market settlement isn't final until the oracle result is confirmed and the redeem transaction lands on-chain, so whether a force-inclusion path exists to push settlement/withdrawal through even under sequencer censorship is part of the protocol's safety story.

If you study this on a given day, add a note link and a ✅ to this line in the source curriculum (docs/knowledge/dev-100-curriculum.md) and this spot will lead straight to the note body. You can also write directly on this page — but regenerating overwrites it, so it's safer to keep anything you want to save as markdown under docs/algorithms/.


한국어

시퀀서 분산화와 강제 포함(force inclusion) TODO

Algorithms · Day 64 / 100 · D. 분산시스템·합의 (Day 52–68)

개념

대부분의 롤업은 트랜잭션 순서를 정하는 시퀀서를 단일 주체가 운영한다. 이 구조는 빠른 확정감과 낮은 지연을 주지만, 그 주체가 특정 사용자의 트랜잭션을 배제하거나 멈추면 사용자가 체인을 쓸 수 없다는 검열·가용성 위험을 남긴다. force inclusion은 이 위험의 하한을 정하는 장치로, 사용자가 시퀀서를 거치지 않고 L1의 inbox 컨트랙트에 트랜잭션을 직접 제출하면 일정 지연 창이 지난 뒤에는 롤업이 그것을 반드시 포함해야 유효한 상태 전이로 인정되게 만든다. 덕분에 시퀀서가 검열해도 사용자는 최소한 출금 같은 탈출 경로를 확보한다. 시퀀서 분산화는 여기서 더 나아가 순서 결정 권한 자체를 여러 주체에 나누는 방향으로, 공유 시퀀서, 지분 기반 로테이션, L1 제안자가 직접 순서를 정하는 방식 등이 시도되며 각각 지연·MEV·복잡도에서 다른 트레이드오프를 갖는다.

L2에 올린 서비스의 최악 시나리오는 시퀀서가 멈추거나 우리 트랜잭션만 배제하는 경우인데, force inclusion 경로의 존재 여부와 지연 창 길이가 그때 자금이 묶이는 시간을 결정한다. 이는 배포 체인을 고르는 실질적 기준이다.

코드 · 수식

# 시퀀서 분산화와 강제 포함(force inclusion) — 시퀀서가 검열해도 L1 inbox를 거치면 지연 창 이후 반드시 포함된다.
# 시퀀서가 특정 발신자를 계속 배제해도, 지연 창(DELAY)이 지난 forced tx는 다음 블록에 강제로 실린다.

DELAY = 3  # 강제 포함까지 걸리는 블록 수

class Sequencer:
    def __init__(self, censored_sender):
        self.censored_sender = censored_sender
        self.included = []

    def build_block(self, block_num, mempool, forced_inbox):
        already = {id(tx) for tx in self.included}
        # 강제 포함 마감이 지난 tx는 검열 여부와 무관하게 반드시 포함해야 유효한 블록이다
        due = [tx for tx in forced_inbox if block_num - tx["submitted_at"] >= DELAY and id(tx) not in already]
        censorable = [tx for tx in mempool if tx["sender"] != self.censored_sender and id(tx) not in already]
        block = due + [tx for tx in censorable if id(tx) not in {id(t) for t in due}]
        self.included.extend(block)
        return block

alice_tx = {"sender": "alice", "tx": "swap", "submitted_at": 0}
mempool = [alice_tx]
forced_inbox = [alice_tx]  # alice가 시퀀서 mempool과 L1 inbox에 동시 제출

seq = Sequencer(censored_sender="alice")
for block_num in range(6):
    block = seq.build_block(block_num, mempool, forced_inbox)
    status = [tx["sender"] for tx in block] if block else "(empty, 시퀀서가 검열 중)"
    print(f"블록 {block_num}: 포함된 tx = {status}")
    if block:
        break

print(f"\n시퀀서가 alice를 계속 배제했지만, 지연 창({DELAY}블록) 이후 강제 포함으로 결국 실렸다:", bool(seq.included))

연습

사용하는 L2의 문서에서 force inclusion(또는 강제 출금) 진입점 컨트랙트와 지연 창을 찾아, 테스트넷에서 L1을 통한 강제 포함 트랜잭션을 한 번 직접 제출해 보라.

실무 · Verex 연결

Verex의 시장 정산은 오라클 결과 확정과 redeem 트랜잭션이 반드시 체인에 실려야 끝나므로, 시퀀서 검열 상황에서도 정산·출금을 밀어 넣을 수 있는 force inclusion 경로가 있는지가 프로토콜 안전성의 일부다.

공부한 날 원본 커리큘럼(docs/knowledge/dev-100-curriculum.md)의 이 줄에 노트 링크와 ✅ 를 붙이면, 이 자리는 노트 본문으로 바로 이어집니다. 노트 없이 이 페이지에 바로 적어도 됩니다 — 다만 다시 생성하면 덮어쓰이므로, 남길 글은 docs/algorithms/ 의 마크다운으로 쓰는 편이 안전합니다.

← 63. 크로스체인 신뢰 가정 분류65. 사기 증명 vs 유효성 증명의 게임 이론 →