x/upgrade
개요
x/upgrade는 실행 중인 Cosmos 체인을 새로운 (호환되지 않는) 소프트웨어 버전으로 원활하게 업그레이드할 수 있도록 하는 Cosmos SDK 모듈의 구현체입니다. 이는 미리 정의된 업그레이드 블록 높이에 도달하면 블록체인 상태 머신이 더 이상 진행되지 않도록 하는 PreBlocker 훅을 제공함으로써 이를 달성합니다.
이 모듈은 거버넌스가 업그레이드를 어떻게 결정하는지에 대해서는 규정하지 않으며, 업그레이드를 안전하게 조정하는 메커니즘만을 제공합니다. 업그레이드에 대한 소프트웨어 지원 없이는 실행 중인 체인을 업그레이드하는 것이 위험합니다. 모든 검증인이 프로세스의 정확히 동일한 지점에서 상태 머신을 일시 중지해야 하기 때문입니다. 이것이 올바르게 수행되지 않으면 복구하기 어려운 상태 불일치가 발생할 수 있습니다.
개념
Plan
x/upgrade 모듈은 실시간 업그레이드가 예정된 Plan 타입을 정의합니다. Plan은 특정 블록 높이에서 예약될 수 있습니다.
Plan은 (동결된) 릴리스 후보와 적절한 업그레이드 Handler(아래 참조)가 합의되면 생성되며, Plan의 Name은 특정 Handler에 해당합니다. 일반적으로 Plan은 거버넌스 제안 프로세스를 통해 생성되며, 투표를 통해 통과되면 예약됩니다. Plan의 Info에는 업그레이드에 대한 다양한 메타데이터가 포함될 수 있으며, 일반적으로 검증인이 자동으로 업그레이드할 수 있는 git commit과 같은 애플리케이션별 업그레이드 정보가 온체인에 포함됩니다.
Sidecar Process
애플리케이션 바이너리를 실행하는 운영자가 바이너리의 자동 다운로드 및 업그레이드를 지원하는 사이드카 프로세스도 실행하는 경우,Info를 통해 이 프로세스를 원활하게 수행할 수 있습니다. 이 도구는 Cosmovisor입니다.
Handler
x/upgrade 모듈은 주요 버전 X에서 주요 버전 Y로의 업그레이드를 용이하게 합니다. 이를 위해 노드 운영자는 먼저 현재 바이너리를 새 버전 Y에 해당하는 Handler가 있는 새 바이너리로 업그레이드해야 합니다. 이 버전은 커뮤니티 전체에서 완전히 테스트되고 승인된 것으로 가정합니다. 이 Handler는 새 바이너리 Y가 체인을 성공적으로 실행하기 전에 어떤 상태 마이그레이션이 발생해야 하는지를 정의합니다. 당연히 이 Handler는 애플리케이션에 따라 다르며 모듈별로 정의되지 않습니다. Handler 등록은 애플리케이션에서 Keeper#SetUpgradeHandler를 통해 수행됩니다.
EndBlock 실행 중에 x/upgrade 모듈은 실행해야 하는(해당 높이에 예약된) Plan이 있는지 확인합니다. 있다면 해당 Handler가 실행됩니다. Plan이 실행될 것으로 예상되지만 Handler가 등록되지 않았거나 바이너리가 너무 일찍 업그레이드된 경우 노드는 정상적으로 패닉하고 종료됩니다.
StoreLoader
x/upgrade 모듈은 업그레이드의 일부로 스토어 마이그레이션도 용이하게 합니다. StoreLoader는 새 바이너리가 체인을 성공적으로 실행하기 전에 발생해야 하는 마이그레이션을 설정합니다. 이 StoreLoader도 애플리케이션에 따라 다르며 모듈별로 정의되지 않습니다. 이 StoreLoader 등록은 애플리케이션에서 app#SetStoreLoader를 통해 수행됩니다.
Plan을 디스크에 기록합니다.
이 정보는 StoreUpgrades가 올바른 높이와 예상된 업그레이드에서 원활하게 발생하도록 하는 데 중요합니다. 이를 통해 새 바이너리가 재시작할 때마다 StoreUpgrades를 여러 번 실행할 가능성을 제거합니다. 또한 동일한 높이에 여러 업그레이드가 계획된 경우 Name은 이러한 StoreUpgrades가 계획된 업그레이드 핸들러에서만 수행되도록 합니다.
Proposal
일반적으로Plan은 MsgSoftwareUpgrade 메시지를 포함하는 제안을 통해 거버넌스에서 제안되고 제출됩니다.
이 제안은 표준 거버넌스 프로세스를 따릅니다. 제안이 통과되면 특정 Handler를 대상으로 하는 Plan이 지속되고 예약됩니다. 업그레이드는 새 제안에서 Plan.Height를 업데이트하여 지연되거나 앞당겨질 수 있습니다.
reference
업그레이드 제안 취소
업그레이드 제안은 취소할 수 있습니다. 거버넌스가 활성화된MsgCancelUpgrade 메시지 타입이 존재하며, 이를 제안에 포함하고 투표하여 통과되면 예약된 업그레이드 Plan이 제거됩니다.
물론 이를 위해서는 업그레이드 자체 전에 투표를 위한 시간을 허용할 수 있도록 업그레이드가 나쁜 아이디어였음을 충분히 미리 알아야 합니다.
reference
2 * (VotingPeriod + DepositPeriod) + (SafetyDelta) 이후여야 합니다. SafetyDelta는 업그레이드 제안이 성공한 후 (외부 사회적 합의로 인해) 나쁜 아이디어였음을 인식하는 데 사용 가능한 시간입니다.
MsgCancelUpgrade 제안은 원래 MsgSoftwareUpgrade 제안이 아직 투표 중인 동안에도 만들 수 있습니다. 단, VotingPeriod가 MsgSoftwareUpgrade 제안 이후에 끝나야 합니다.
상태
x/upgrade 모듈의 내부 상태는 비교적 최소하고 간단합니다. 상태는 키 0x0으로 현재 활성화된 업그레이드 Plan(존재하는 경우)을 포함하고, 키 0x1으로 Plan이 “완료”로 표시되었는지를 포함합니다. 상태는 애플리케이션의 모든 앱 모듈의 합의 버전을 포함합니다. 버전은 big endian uint64로 저장되며, string 타입의 해당 모듈 이름이 추가된 접두사 0x2로 액세스할 수 있습니다. 상태는 키 0x3으로 액세스할 수 있는 Protocol Version을 유지합니다.
- Plan:
0x0 -> Plan - Done:
0x1 | byte(plan name) -> BigEndian(Block Height) - ConsensusVersion:
0x2 | byte(module name) -> BigEndian(Module Consensus Version) - ProtocolVersion:
0x3 -> BigEndian(Protocol Version)
x/upgrade 모듈은 genesis 상태를 포함하지 않습니다.
이벤트
x/upgrade는 자체적으로 이벤트를 발생시키지 않습니다. 모든 제안 관련 이벤트는 x/gov 모듈을 통해 발생됩니다.
클라이언트
CLI
사용자는 CLI를 사용하여upgrade 모듈을 쿼리하고 상호작용할 수 있습니다.
쿼리
query 명령을 사용하여 upgrade 상태를 쿼리할 수 있습니다.
applied
applied 명령을 사용하여 완료된 업그레이드가 적용된 높이의 블록 헤더를 쿼리할 수 있습니다.
module versions
module_versions 명령은 모듈 이름과 해당 합의 버전 목록을 가져옵니다.
명령 뒤에 특정 모듈 이름을 지정하면 해당 모듈의 정보만 반환됩니다.
plan
plan 명령은 현재 예약된 업그레이드 계획(존재하는 경우)을 가져옵니다.
트랜잭션
upgrade 모듈은 다음 트랜잭션을 지원합니다:software-proposal- 업그레이드 제안을 제출합니다:
cancel-software-upgrade- 이전에 제출된 업그레이드 제안을 취소합니다:
REST
사용자는 REST 엔드포인트를 사용하여upgrade 모듈을 쿼리할 수 있습니다.
Applied Plan
AppliedPlan은 이름으로 이전에 적용된 업그레이드 계획을 쿼리합니다.
Current Plan
CurrentPlan은 현재 업그레이드 계획을 쿼리합니다.
Module versions
ModuleVersions는 상태에서 모듈 버전 목록을 쿼리합니다.
gRPC
사용자는 gRPC 엔드포인트를 사용하여upgrade 모듈을 쿼리할 수 있습니다.
Applied Plan
AppliedPlan은 이름으로 이전에 적용된 업그레이드 계획을 쿼리합니다.
Current Plan
CurrentPlan은 현재 업그레이드 계획을 쿼리합니다.
Module versions
ModuleVersions는 상태에서 모듈 버전 목록을 쿼리합니다.
리소스
x/upgrade 모듈에 대해 더 알아보기 위한 (외부) 리소스 목록입니다.
- Cosmos Dev Series: Cosmos Blockchain Upgrade - 소프트웨어 업그레이드가 어떻게 작동하는지 자세히 설명하는 블로그 포스트입니다.
