protocol-versions

작성자: convex-dev

프로토콜 버전, 마이그레이션 및 v1 업그레이드 — 어떤 의미론을 기준으로 작성할지, 그리고 네트워크를 포크하지 않고 CVM 동작을 변경하는 방법. 다음 경우에 사용하세요…

npx skills add https://github.com/convex-dev/convex --skill protocol-versions

Protocol Versions and Migrations

The protocol version is the count of upgrades applied to a network, starting at 0 at genesis. Genesis is immutable — it is the network's identity — so every change to CVM semantics after launch arrives as a scheduled migration that increments the version by exactly 1.

Full design: convex-core/docs/UPGRADE.md. Read it before authoring a migration; this skill is orientation and conventions.

Write Against v1

v1 is the target. It is the first upgrade, it bundles every bug known at genesis, and it is what networks will be running. Unless you are specifically reasoning about live or historical behaviour, v1 semantics are the semantics.

This is the project's own test convention — three state roles, each answering a different question:

RoleVersionUse
Target — InitTest.UPGRADED / BaseTest.UPGRADEDMAX_VERSIONThe ACVMTest default. Libraries, actors and CVM behaviour are tested against where the network is going.
LIVE — InitTest.LIVE / BaseTest.LIVEMigrations.LIVE_VERSIONThe release gate: what live peers run today, so a release does not break them before they upgrade.
Genesis — InitTest.STATE / BaseTest.STATE0Pinned where genesis is the point: genesis-hash invariants, replay (SnapshotStateTest), and intended-diff contrast tests (MigrationFixesTest).

Migrations.LIVE_VERSION is bumped when, and only when, the live network applies an upgrade. Everything pinned to LIVE follows automatically.

What v1 Contains

The bootstrap — installing schedule-upgrade / unschedule-upgrade plus the new core functions gensym, cat, splice and char? (#92) — and fixes that could not ship any other way, because a naive fix would move the genesis hash:

MigrationFixes
v1-core.cvxupdate / update-in variadic arities (#533); quasiquote of sets/maps, ~false, define double-evaluation, call arity (#598); macro hygiene for dotimes / for / for-loop / switch (#602)
v1-trust.cvxtrusted? now fails closed against defective monitors (#623)
v1-fungible.cvxadd-mint :max-supply defaults to unlimited rather than 0 (#528)
v1-asset.cvx, v1-box.cvx, v1-delegate.cvx, v1-metadata.cvx, v1-multi-token.cvx, v1-nft-basic.cvx, v1-nft-simple.cvxlibrary fixes (#600, #620, #621, #622, #623)

Two of these change behaviour agents rely on — see the trust and token skills, which document the v1 behaviour and flag the pre-v1 trap.

Changing CVM Behaviour

Where the change lives determines the strategy.

Tier 1 — state-resident core. Functions defined in core.cvx are compiled into account #8 at genesis; they are state. Fix by migration: replace the binding with the recompiled definition. No Java version branch.

Caveat: the compiler statically links core symbols, so already-deployed actors keep the old embedded function unless the migration also sweeps environments. Whether to sweep is a per-upgrade decision.

Tier 2 — native semantics. Opcodes, native core functions, juice costs and cast rules are the transition function, in Java. These change by version-keyed dispatch:

long cost = (state.getProtocolVersion() >= 3) ? Juice.NEW_COST : Juice.OLD_COST;

Whether a gate is needed is decided by replay evidence, not judgement. Make the change unconditional locally and run SnapshotStateTest: if the replay hash moves, recorded history exercised the old semantics and the gate is mandatory; if not, it ships unconditionally with no permanent branch. Branches are permanent — replay from genesis needs every historical semantics.

Adding a core function means a new core definition code, registered with regNonGenesis and installed by a migration — never into genesis. Standing rule (amended 2026-08-13): no release adds a code beyond 506 unless it ships, in the same release, at minimum a 506-style in-definition version gate — fail-first below the introducing version, before arity checking or any other work (char?, code 506, is the model). Once v1 has activated on the live network, full versioned materialisation is required instead. Rationale: the decode-skew policy in UPGRADE.md.

Tier 3 — encodings. Decoding happens outside any state context, so it cannot branch on version. Decoders stay permissive of all historical forms forever; the version gates what the CVM writes and canonicalises. See the cad3-encoding skill — this is why a permissive decoder is correct rather than a bug.

Authoring a Migration

  • Purity is a hard contract. A migration is State → State with no clock, randomness or I/O. An impure migration forks the network.
  • The list is append-only forever. Position is identity — Migrations.get(k) produces version k+1 — so never insert or reorder.
  • Test the exact delta. Every migration needs tests asserting precisely what changed and that nothing else did (compare untouched subtrees by hash).
  • Failure at an activation boundary makes peers withdraw from consensus rather than produce a state — a stall is recoverable, divergence is not.

MigrationFixesTest owns the intended differences between genesis and upgraded semantics; add to it when a migration changes observable behaviour.

Fresh Networks

Launchers that create a new genesis (local start, peer genesis, peer start --genesis, GUI local networks) apply all migrations at creation, so a fresh network starts at MAX_VERSION — it has no history to preserve and should not launch with known-fixed bugs.

Pin a lower version with --protocol-version (CLI) or :protocol-version (peer config) to mirror a network that has not yet upgraded. This is how you reproduce live behaviour locally while v1 is pending.

convex-dev의 다른 스킬

convex-lisp
convex-dev
Convex Lisp 언어 참조 — CVM 규칙, 라이브러리 코드 호출, 액터 정의, juice 및 오류 코드. CVM 소스를 작성하거나 디버깅할 때 사용합니다…
ecosystem
convex-dev
Convex 생태계에서의 방향 안내 — 어떤 리포지토리에 무엇이 있는지, 사양과 문서가 어디에 있는지, 그리고 어떤 클라이언트 라이브러리가 존재하는지. 컨텍스트가 필요할 때 사용하세요…
local-network
convex-dev
로컬 Convex 테스트 네트워크를 개발용으로 실행합니다. 라이브 네트워크에 대한 변경 사항을 테스트하거나, 피어 문제를 재현하거나, 원격 네트워크가 없을 때 사용합니다.
etch
convex-dev
Etch 스토어를 검사하고 유지 관리합니다 — Convex의 콘텐츠 주소 지정 데이터베이스입니다. 피어 저장소를 검사하거나, 손상을 진단하거나, 가비지 컬렉션을 수행할 때 사용합니다.
juice
convex-dev
Juice 회계 — CVM에서의 연산 및 대역폭 비용. 트랜잭션 실행 비용을 추론하거나, :JUICE 실패를 진단하거나, …할 때 사용합니다.
trust
convex-dev
Trust 모니터 — Convex의 구성 가능한 온체인 인가 모델. 접근 제어 작성, 액터 함수 제한, 발행 권한 정의 시 사용합니다…
memory
convex-dev
메모리 회계 및 허용량 — 온체인 저장 비용, 그리고 이를 최소화하고 회수하는 방법. 상태 성장에 대해 추론하거나, 진단할 때 사용하세요…
peer
convex-dev
Convex 피어를 운영합니다 — 네트워크 제네시스를 생성, 시작, 나열, 백업 또는 인스턴스화합니다. 네트워크에 대해 피어를 실행하거나 새 네트워크를 설정할 때 사용합니다.