EIP-8148 검증자 맞춤 스위프 임계값 (Custom sweep threshold for validators)

Hegota 포함 검토 (CFI) · 합의·스테이킹 · 원문 상태 Draft · 2026-02-05 작성

합산 출금 자격(0x02)을 쓰는 검증자가 보상이 자동으로 출금 주소로 빠져나가는 잔액 기준을 32 ETH와 2,048 ETH 사이에서 직접 정할 수 있게 합니다.

왜 필요한가

지금 합산 출금 자격(0x02) 검증자는 잔액이 2,048 ETH를 넘어야 초과분이 자동으로 출금 주소로 옮겨집니다. 이 기준이 너무 높다고 느끼는 검증자가 많아 0x02로 전환하는 비율이 매우 낮다고 원문은 설명합니다. 대안인 부분 출금은 사용자가 직접 트랜잭션을 보내야 하고 일반 퇴장 대기열을 함께 쓰기 때문에 요청부터 처리까지 걸리는 시간을 예측하기 어렵습니다. 원문은 2025년 10월 퇴장 대기열이 급증한 사례를 듭니다. 예를 들어 128 ETH 검증자는 한 주에 약 0.07 ETH를 보상으로 받는데, 이 작은 금액을 받으려고 매번 부분 출금 트랜잭션을 보내는 것은 무리입니다. 잔액을 계속 지켜보다가 직접 요청해야 하는 부담도 있습니다. 이 제안은 검증자가 원하는 기준을 한 번 정해 두면, 그 위로 쌓인 보상이 스위프(sweep) 주기에 맞춰 자동으로 출금되게 합니다. 기본 동작은 그대로이고 원하는 검증자만 쓰는 선택 기능입니다.

무엇이 바뀌나

지금

EIP-8148 이후

누구에게 영향이 있나

심층 설명

실행 계층 요청 형식과 컨트랙트 입력

이 EIP는 EIP-7685 요청 타입 SWEEP_THRESHOLD_REQUEST_TYPE(0x05)을 추가합니다. 요청은 source_address(Bytes20), validator_pubkey(Bytes48), threshold(uint64, Gwei 단위) 세 필드로 구성됩니다. 전용 컨트랙트 SET_SWEEP_THRESHOLD_REQUEST_PREDEPLOY_ADDRESS에 정확히 56바이트를 보내면 0:48은 검증자 공개키, 48:56은 빅엔디언 uint64 기준값으로 해석합니다. 컨트랙트는 msg.value가 get_fee() 이상인지 확인하고 블록 요청 수를 1 늘립니다. 대기열 슬롯 3개에는 msg.sender, 공개키 앞 32바이트, 공개키 뒤 16바이트와 기준값을 저장합니다. 그리고 source_address(20) ++ validator_pubkey(48) ++ threshold(8) 76바이트를 LOG0으로 남깁니다. 엔디언에 주의해야 합니다. 입력과 로그의 threshold는 빅엔디언이지만 시스템 콜이 돌려주는 값과 EIP-7685 인코딩은 리틀엔디언입니다.

수수료와 블록당 처리 한도

요청 수수료는 EIP-7002와 같은 방식으로 정해집니다. MIN_SET_SWEEP_THRESHOLD_REQUEST_FEE는 1, TARGET_SET_SWEEP_THRESHOLD_REQUESTS_PER_BLOCK은 2, SET_SWEEP_THRESHOLD_REQUEST_FEE_UPDATE_FRACTION은 17입니다. 누적 초과량(excess)을 fake_exponential에 넣어 수수료를 계산합니다. 블록마다 요청 수가 목표인 2건을 넘으면 초과량이 쌓여 수수료가 오르고 밑돌면 줄어듭니다. 한 블록에서 대기열에서 꺼내는 요청은 MAX_SET_SWEEP_THRESHOLD_REQUESTS_PER_BLOCK인 16건까지입니다. 입력 길이가 0이면 현재 수수료를 돌려주는 조회로 처리합니다. 이때 ETH가 함께 오면 자금 손실을 막기 위해 되돌립니다. 첫 시스템 콜 전에는 초과량 슬롯에 EXCESS_INHIBITOR(2**256-1)가 들어 있어 get_fee()가 실패합니다.

블록 끝 시스템 콜 규칙

FORK_BLOCK부터 모든 블록은 트랜잭션 처리가 끝난 뒤 SYSTEM_ADDRESS(0xfffffffffffffffffffffffffffffffffffffffe)가 빈 calldata로 컨트랙트를 호출합니다. 컨트랙트는 대기열에서 요청을 꺼내고(dequeue_set_sweep_threshold_requests), 초과량을 갱신하고(update_excess_set_sweep_threshold_requests), 블록 요청 수를 0으로 되돌립니다. 꺼낸 요청은 SSZ로 직렬화해 이어 붙인 바이트열로 반환하며 EIP-7685 요청 목록에 그 순서 그대로 들어가야 합니다. 이 호출은 SYSTEM_TRANSACTION_GAS인 30_000_000 가스를 따로 받고 EIP-7825의 트랜잭션 가스 상한을 받지 않습니다. 쓴 가스는 블록 가스 사용량에 포함되지 않고 EIP-1559 소각도 없습니다. 컨트랙트 주소에 코드가 없거나 호출이 실패하면 블록은 무효입니다. EIP-7910 eth_config를 제공하는 클라이언트는 systemContracts에 SET_SWEEP_THRESHOLD_REQUEST_PREDEPLOY_ADDRESS 키로 이 컨트랙트를 적어야 합니다.

출금 자격 안에 기준값 저장

합의 계층은 BeaconState나 Validator에 필드를 추가하지 않고 0x02 출금 자격 안에 기준값을 넣습니다. 0번째 바이트는 COMPOUNDING_WITHDRAWAL_PREFIX(0x02), 1~2번째 바이트는 EFFECTIVE_BALANCE_INCREMENT 단위의 리틀엔디언 uint16 기준값, 3~11번째는 예약, 12~31번째는 실행 주소입니다. 상수 SWEEP_THRESHOLD_CREDENTIAL_OFFSET은 1, SWEEP_THRESHOLD_CREDENTIAL_LENGTH는 2입니다. 기준값이 MAX_EFFECTIVE_BALANCE_ELECTRA이면 0으로 저장하고 범위를 벗어난 값은 기본값으로 읽습니다. 예를 들어 0x02e803...은 1,000 ETH입니다. 스위프와 유효 잔액 계산에서 get_max_effective_balance를 쓰던 자리는 모두 이 기준값을 씁니다. 따라서 기준값은 자동 출금 기준이면서 유효 잔액 상한이기도 합니다. 근거 절은 검증자마다 8바이트 목록을 BeaconState에 추가하면 balances만큼 커지는데, 자격에는 이미 11바이트가 비어 있고 switch_to_compounding_validator가 자격을 다시 쓰는 경로도 있어 여기에 넣었다고 설명합니다. 최대값을 0으로 저장하면 모든 기준값이 인코딩 하나만 갖고 검증자가 원래 자격으로 되돌릴 수도 있습니다.

요청 수락 조건과 처리 시점

기준값 변경 요청은 다음 조건을 모두 만족할 때만 받아들입니다. source_address가 검증자의 실행 주소여야 하고 대상은 퇴장 중이 아닌 합산 출금 검증자여야 합니다. 기준값은 EFFECTIVE_BALANCE_INCREMENT의 배수이고 MIN_ACTIVATION_BALANCE 이상 MAX_EFFECTIVE_BALANCE_ELECTRA 이하이며 검증자의 현재 잔액보다 낮으면 안 됩니다. 현재 잔액 아래로 잡지 못하게 한 이유는 이 기능으로 즉시 출금을 일으키는 것을 막기 위해서입니다. 더 낮은 기준을 원하면 먼저 부분 출금으로 잔액을 줄인 뒤 요청하면 됩니다. 새 0x02 검증자는 자신을 만든 예치의 자격에서 기준값을 가져오고(범위 밖이면 지움), 초기 유효 잔액은 그 기준값까지로 제한됩니다. switch_to_compounding_validator와 포크 전환은 1~2번째 바이트를 지워 기존 검증자와 전환 검증자는 기본값에서 시작합니다. 요청은 부분 출금과 달리 합의 계층 대기열 없이 실행 계층에서 꺼내는 즉시 처리됩니다. ExecutionRequests에 SetSweepThresholdRequest 목록이 추가되고 페이로드당 최대 MAX_SET_SWEEP_THRESHOLD_REQUESTS_PER_PAYLOAD(16)건입니다.

호환성, 대기열 중단 장치, 보안

블록 구조와 검증 규칙이 바뀌므로 하위 호환되지 않지만 사용자 활동과 경험에는 영향이 없다고 원문은 밝힙니다. ExecutionRequests에 새 타입이 들어가므로 포크 시점에 execution_requests_root 검증을 클라이언트 간에 맞춰야 합니다. 기준값을 바꾸면 자격의 1~2번째 바이트가 달라지므로, 32바이트 전체를 비교하는 EIP-4788 증명 검증기 같은 앱은 접두어와 실행 주소만 비교해야 합니다. 변경은 출금 주소만 요청할 수 있어 선택 사항입니다. 이 EIP 이전 도구로 만든 예치는 그 바이트가 0이므로 기본값을 받습니다. 시스템 콜에 빈 calldata가 아닌 값이 오면 초과량 슬롯에 EXCESS_INHIBITOR를 넣어 대기열을 멈춥니다. 이 EIP에서는 모든 시스템 콜이 빈 calldata이므로 닿지 않는 경로이지만 나중에 컨트랙트를 폐기할 때 프로토콜이 호출을 멈춘 뒤에도 요청과 수수료가 빠지지 않는 대기열에 계속 쌓이는 일을 막기 위해 둔 장치입니다. 수수료 과다 지불, 시스템 콜 실패, 빈 코드 같은 보안 고려 사항은 EIP-7002와 같다고 적고 있습니다.

현재 상태와 포크 결정

이 EIP는 Draft 상태이며 아직 바뀔 수 있습니다. 컨트랙트 주소 SET_SWEEP_THRESHOLD_REQUEST_PREDEPLOY_ADDRESS와 배포 트랜잭션은 원문에 TBD로 비어 있고 합의 계층 전체 명세는 specs/_features/eip8148/beacon-chain.md에 따로 있습니다. 코어 개발자 콜에서는 09.03 ACDC #186에서 논의됐지만 결정은 없었고 10.29 ACDC #190에서 헤고타(Hegota) 포크의 CFI로 정해졌습니다. CFI는 Considered for Inclusion의 약자로 포크 포함 후보로 검토한다는 뜻입니다.

EIP 원문 · ← EIPs