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

# 엔진 아키텍처

> 0x1 Rust 기반 미러 트레이딩 엔진에 대한 기술 백서로, 레거시 카피 트레이딩 시스템의 순차 처리 및 슬리피지 문제와 비교·분석합니다.

## 개요

0x1은 Rust 네이티브 미러 트레이딩 엔진을 운영합니다. 이 엔진은 리더의 체결 내역을 이질적인 팔로워 계정 집합에 1초 이하의 레이턴시, 제한된 슬리피지, 계정별 리스크 격리로 복제하도록 설계되었습니다. 본 문서는 해당 엔진의 아키텍처를 명세하고, 기존 카피 트레이딩 스택의 특성인 순차 실행 및 무제한 슬리피지 패턴과 비교합니다. 이하에서 설명하는 설계 선택 — 트레이더별 병렬 파이프라인, 병렬 팬아웃, 오더북 인식 사전 검사, 비수탁형 EIP-712 서명 — 은 0x1이 리더-팔로워 복제 범위를 압축하고 팔로워가 가입 시 기대한 PnL 형태를 보존하는 메커니즘입니다.

## 1. 문제 정의: 레거시 카피 트레이딩

대부분의 기존 카피 트레이딩 구현체는 고빈도 파생상품 거래소를 위해 설계되지 않은 아키텍처를 그대로 답습합니다. 그 결과 나타나는 실행 병폐는 네 가지 반복적인 유형으로 분류됩니다.

### 1.1 순차적 주문 처리

레거시 시스템은 단일 스레드 루프에서 팔로워를 순서대로 순회합니다. 리더의 주문이 체결되면 시스템은 `N`명의 팔로워를 열거하고 주문을 하나씩 순서대로 제출하며, 다음 팔로워로 넘어가기 전에 각 HTTP 왕복과 거래소 확인 응답을 블로킹 방식으로 기다립니다. 정상 상태에서 k번째 팔로워가 체결되는 시간은 대략 다음과 같습니다:

$$
t_k \approx t_{\text{leader}} + k \cdot (t_{\text{rtt}} + t_{\text{match}})
$$

`N = 500`명의 팔로워, 30ms 왕복 지연, 10ms 매칭 지연 시, 마지막 팔로워는 리더보다 **20초** 늦게 체결됩니다 — 무기한 선물 거래소에서는 치명적인 시간 차이입니다.

### 1.2 무제한 슬리피지

주문 크기는 리더의 명목 금액을 기준으로 산정되어 체결 시 시장가로 제출되기 때문에, 나중에 처리되는 팔로워들은 반복적으로 자신의 오더북을 소진시킵니다. 각 체결은 점점 더 불리한 가격에서 유동성을 소진하며, 실현 슬리피지가 팔로워의 허용치를 초과할 때 팬아웃을 중단하는 피드백 루프가 없습니다. 동일한 리더의 거래가 팔로워 전체에 걸쳐 심하게 좌편향된 PnL 분포를 만들어냅니다.

### 1.3 폴링 기반 신호 감지

많은 시스템이 사용자 데이터 스트림을 구독하는 대신 몇 초마다 거래소 REST API를 폴링하여 리더 활동을 감지합니다. 따라서 리더의 체결이 복제 파이프라인에 진입할 때는 이미 오래된 타임스탬프를 달고 있어, 위에서 언급한 대기 지연을 더욱 악화시킵니다.

### 1.4 공유 장애 모드

순차 루프에서 단 하나의 잘못된 주문, 속도 제한 차단, 또는 HTTP 타임아웃이 발생하면 뒤에 있는 모든 팔로워가 멈춥니다. 한 리더의 파이프라인을 다른 리더의 파이프라인으로부터 격리하는 격벽이 없고, 하나의 계정에 발생한 나쁜 순간이 연쇄적으로 다음 계정에 영향을 미치는 것을 막는 팔로워별 서킷 브레이커도 없습니다.

## 2. 0x1 엔진: 설계 목표

0x1 엔진은 네 가지 불변 조건을 목표로 합니다:

| 불변 조건          | 정의                                                       |
| -------------- | -------------------------------------------------------- |
| **낮은 복제 레이턴시** | 팔로워 체결 중앙값이 리더 체결 후 1초 이내에 이루어집니다.                       |
| **제한된 슬리피지**   | 어떤 팔로워도 설정된 슬리피지 허용치를 벗어나 체결되지 않습니다.                     |
| **비례 크기 산정**   | 팔로워의 포지션 변화량은 리더의 마진 변화량의 고정 비율이며, 절대 크기를 그대로 복제하지 않습니다. |
| **장애 격리**      | 한 리더 파이프라인 또는 한 팔로워 계정의 장애가 다른 어떤 것도 블로킹하지 않습니다.         |

## 3. 아키텍처

### 3.1 런타임

핫 패스는 [Tokio](https://tokio.rs) 비동기 런타임 위에서 Rust로 구현되었습니다. 각 리더는 독립적인 수퍼바이저 태스크가 담당하며, 각 팔로워 구독은 Tokio 익스큐터에서 협력적으로 스케줄링되는 경량 태스크입니다. 엔진은 크리티컬 패스에서 동기 락을 전혀 보유하지 않으며 — 모든 상태 핸드오프는 유계 MPSC 채널을 사용하고, 백프레셔는 명시적입니다.

### 3.2 트레이더별 병렬 파이프라인

팔로워가 있는 모든 트레이더는 아웃바운드 신호 채널만 공유하고 나머지는 완전히 독립된 세 개의 동시 스트림으로 실행됩니다:

```mermaid theme={"system"}
flowchart LR
  subgraph Leader pipeline
    OB["Orderbook stream<br/>(WebSocket)"]
    UA["User-account stream<br/>(WebSocket)"]
    EX["Executor task"]
  end
  UA -->|fill event| SG["Signal generator"]
  OB -->|top-of-book| SG
  SG --> RG["Risk guard"]
  RG -->|sized & validated| FA["Parallel fanout"]
  FA -. task .-> F1["Follower A<br/>signer task"]
  FA -. task .-> F2["Follower B<br/>signer task"]
  FA -. task .-> F3["Follower C<br/>signer task"]
```

오더북 스트림과 사용자 계정 스트림이 독립적인 WebSocket 구독으로 운영되기 때문에, 리더의 체결은 폴링 주기가 아닌 푸시 패스에서 감지됩니다. 신호 생성기는 Aster가 체결을 게시하는 즉시 타입화된 `MirrorIntent`를 생성하며, 다음 REST 틱을 기다리지 않습니다.

### 3.3 병렬 팬아웃

팬아웃 단계는 모든 적격 팔로워에 대해 `FuturesUnordered`로 구현됩니다. 각 팔로워는 자체 서명자와 Aster에 대한 자체 아웃바운드 HTTP 연결을 소유한 별개의 Tokio 태스크입니다. k번째 팔로워는 더 이상 (k-1)번째를 기다리지 않으며 — 모든 서명, 리스크 검사, 주문 제출이 동시에 이루어집니다.

순차 모델에서는 마지막 팔로워의 레이턴시가 `N`에 선형으로 증가합니다. 0x1 모델에서는 `N`에 대해 로그함수적으로 증가하며(스케줄러 + 커넥션 풀 한계), 단일 RTT가 지배적입니다:

$$
t_k \approx t_{\text{leader}} + t_{\text{rtt}} + t_{\text{match}} \quad \forall k \text{ (동시성 상한 내)}
$$

### 3.4 오더북 인식 사전 검사

팔로워 태스크가 제출하기 전에, 리스크 가드는 실시간 오더북 스냅샷을 다시 읽어 팔로워의 설정된 슬리피지 허용치에 대한 예상 체결을 계산합니다. 허용치를 초과할 것으로 예상되는 주문은 전송되지 않고 **건너뜁니다** — 그리고 해당 건너뜀은 구조화된 이유 코드와 함께 팔로워의 활동 로그에 기록됩니다. 500명의 팔로워가 순차적으로 자신의 오더북을 소진시키는 레거시 장애 모드는, 예상 마크가 한계를 초과하면 주문 자체가 발송되지 않기 때문에 발생할 수 없습니다.

### 3.5 비례 크기 산정

팔로워의 크기는 팔로워의 설정 할당(Allocation)과 리더의 마진 변화량의 함수입니다:

$$
\text{size}_{\text{follower}} = \text{size}_{\text{leader}} \cdot \frac{\text{alloc}_{\text{follower}}}{\text{margin}_{\text{leader}}}
$$

팔로워의 레버리지 상한 및 Aster의 최소 주문 크기에 의해 제한됩니다. 엔진은 절대 명목 금액을 복제하지 않으며, 리더의 리스크 커밋 형태를 팔로워의 대차대조표에 비례하여 복제합니다.

### 3.6 비수탁형 서명

엔진은 핫 패스에서 팔로워의 원시 개인 키를 절대 보지 않습니다. 각 팔로워는 트레이딩 계정 범위로 제한된 EIP-712 ECDSA 페이로드에 서명하는 에이전트 키를 프로비저닝합니다. 에이전트 키는 저장 시 암호화되고 필요에 따라 교체됩니다. 팔로워는 Aster 잔고와 에이전트를 승인하는 마스터 키 모두의 커스터디를 유지합니다.

## 4. 비교 분석

<Tabs>
  <Tab title="팬아웃 레이턴시">
    | 속성            | 레거시 순차                  | 0x1 엔진          |
    | ------------- | ----------------------- | --------------- |
    | k번째 팔로워 체결    | $O(k \cdot \text{RTT})$ | $O(\text{RTT})$ |
    | N=500 마지막 팔로워 | ≈ 20초                   | ≈ 1초            |
    | 신호 감지         | REST 폴링                 | WebSocket 푸시    |
  </Tab>

  <Tab title="슬리피지 프로필">
    | 속성            | 레거시 순차   | 0x1 엔진   |
    | ------------- | -------- | -------- |
    | 발송 전 검사       | 없음       | 오더북 재읽기  |
    | 슬리피지 한계       | 암묵적, 무제한 | 팔로워별 명시적 |
    | 후발 팔로워 PnL 편향 | 심한 좌편향   | 허용치로 제한  |
  </Tab>

  <Tab title="장애 격리">
    | 속성        | 레거시 순차     | 0x1 엔진      |
    | --------- | ---------- | ----------- |
    | 팔로워 간 블로킹 | 있음         | 없음 (태스크별)   |
    | 리더 간 블로킹  | 있음 (공유 루프) | 없음 (수퍼바이저별) |
    | 불량 주문 격리  | 전체 배치 정지   | 단일 태스크 실패   |
  </Tab>

  <Tab title="커스터디">
    | 속성       | 레거시 순차      | 0x1 엔진             |
    | -------- | ----------- | ------------------ |
    | 서버의 키 자료 | 평문 / KMS 지원 | 암호화된 에이전트 키만       |
    | 서명 범위    | 범위 없음       | EIP-712 범위 제한 페이로드 |
    | 철회       | 플랫폼 측       | 팔로워 측              |
  </Tab>
</Tabs>

## 5. 운영 범위

<AccordionGroup>
  <Accordion title="리더가 거래를 멈춘 경우">
    수퍼바이저는 청산을 합성하지 않습니다. 팔로워의 열린 포지션은 리더가 청산하거나 팔로워가 대시보드에서 직접 청산할 때까지 열린 상태로 유지됩니다. 엔진은 부재로부터 의도를 추정하지 않습니다.
  </Accordion>

  <Accordion title="팔로워 마진 소진">
    리스크 가드는 어떤 주문이 서명되기 전에 `MarginBreach` 건너뜀을 반환합니다. 팔로워를 대신하여 레버리지 추가 충전이 이루어지지 않습니다. 활동 로그는 시도한 크기와 설정된 상한과 함께 위반 내용을 기록합니다.
  </Accordion>

  <Accordion title="거래소 속도 제한">
    각 팔로워 연결은 자체 토큰 버킷 속도 제한기를 보유합니다. 팔로워가 버킷 한도에 도달하면 해당 팔로워의 태스크만 백프레셔가 적용되며, 다른 팔로워와 다른 리더는 영향을 받지 않습니다.
  </Accordion>

  <Accordion title="리더의 부분 체결">
    신호 생성기는 각 부분 체결에 대해 증분 `MirrorIntent` 메시지를 발행합니다. 팔로워 크기는 매 발행 시마다 새로운 리더 마진 변화량에 대해 재계산됩니다.
  </Accordion>
</AccordionGroup>

## 6. 결론

레거시 카피 트레이딩 스택은 현대 무기한 거래소와 조합되지 않는 배치 지향적, REST 폴링 방식, 단일 스레드 가정의 산물입니다. 0x1 엔진은 그러한 스택을 푸시 구동, 트레이더별 병렬, 오더북 인식 설계로 대체합니다. 이 설계에서 팔로워 추가 비용은 RTT가 아닌 태스크 핸들입니다. 그 결과는 팔로워의 실현 PnL 분포가 제한적이고 명시적인 편차 범위 내에서 리더를 추적하는 복제 환경이며 — 한 계정의 나쁜 순간이 결코 다음 계정의 위기로 번지지 않습니다.

<Note>
  엔진은 비수탁형입니다. 모든 팔로워 잔고는 Aster에 남아 있으며, 모든 서명은 팔로워가 언제든지 철회할 수 있는 팔로워 범위 에이전트 키를 사용합니다.
</Note>
