수이(Sui)는 어제 런칭 이후 가장 큰 실행 계층 업그레이드를 예고했다. 겉으로는 "더 빠르고, 캐싱이 생기고, 차세대 Move 기능을 준비한다"는 요약이 전부처럼 보이지만, 그러나 이번 업데이트는 실행 엔진에서 생각보다 더 큰 패러다임의 전환이 발생했다. 이에 이번 업그레이드로 인해 발생하는 변경사항들을 깃허브에 올라온 코드를 기준으로 살펴보았다.
수이의 실행 엔진은 프로토콜 버전별로 격리되어 관리되며, 이번 업데이트로 실행 엔진은 v3로 업데이트된다. v3의 핵심은 static_programmable_transactions라는 완전히 새로운 실행 파이프라인의 도입이며, 프로토콜 설정 플래그 하나로 기존 경로와 새 경로를 분기한다.
1.1.1 기존 방식: 실행하면서 확인
기존 v2의 실행 모델은 단순했다. PTB(Programmable Transaction Block)의 명령어들을 순서대로 하나씩 꺼내서, 각 명령어를 실행하는 시점에 타입을 확인하고, borrow 규칙을 검증하고, 결과를 반환하는 구조다. 기존에는 이 과정이 단일 파일(execution.rs) 안에서 모든 것이 이루어졌다.
이 방식은 직관적이지만 구조적인 한계가 있다. 런타임에 모든 검증이 이루어지기 때문에 실행 도중에야 타입 불일치나 borrow 위반을 발견할 수 있고, 패키지 로딩이나 타입 해석의 결과를 재사용하기 어렵다. 네트워크 규모가 작을 때는 문제가 없었지만, 수이의 온체인 패키지 수가 늘어나고 트랜잭션 복잡도가 높아지면서 이 구조가 병목이 되기 시작한 것이다.
1.1.2 새 방식: 분석 후 실행
v3의 새 파이프라인은 트랜잭션을 즉시 실행하지 않는다. 대신, 컴파일러처럼 여러 단계를 거쳐 트랜잭션을 분석하고 검증한 뒤에 실행한다.
단계를 하나씩 풀어보자.
Loading: 원본 트랜잭션의 입력값들을 분류하고, 참조하는 패키지와 함수들을 로딩하여 중간 표현(Loading AST)을 만든다. 이 과정에서 CachedPackageStore가 이미 로딩된 패키지를 캐싱해둔다.
Typing: Loading AST를 바탕으로 각 명령어의 입력 타입과 반환 타입을 정적으로 추론한다. 그리고 이 타입 정보를 기반으로 메모리 안전성, drop 안전성, 입력 인자 호환성 등을 실행 전에 검증한다. 새 VM에서 가장 비중이 큰 부분이다.
Execution: 타입이 확정되고 검증까지 완료된 Typed AST를 실행한다. 런타임에서 추가적인 타입 체크가 거의 필요 없으므로 실행 자체가 가벼워진다.
코드 규모만 봐도 변화의 크기를 실감할 수 있다. 기존 실행 코어가 약 3,500줄이었던 것에 비해, 새 파이프라인은 10,529줄로 3배 가까이 늘어났다. 단순히 코드가 늘어난 것이 아니라, 실행 전에 해야 할 일이 그만큼 많아졌다는 뜻이다.
런타임 동적 해석에서 실행 전 정적 분석으로의 전환은, 단순한 최적화가 아니라 실행 엔진의 설계 철학 자체가 바뀌는 것이다. 이는 향후 더 복잡한 트랜잭션 패턴이 등장하더라도 안정적으로 처리할 수 있는 기반이 된다.
Loading, Typing, Execution이 명확히 분리됨으로써, 각 단계를 독립적으로 최적화하거나 교체할 수 있는 여지가 생겼다. 예를 들어 향후 JIT 컴파일이나 AOT 컴파일 같은 고급 최적화를 도입할 때, Typed AST를 입력으로 받는 새로운 Execution 백엔드를 추가하는 것이 가능해진다.
새 VM의 또 다른 핵심 변화는 CachedPackageStore의 도입이다.
기존에는 패키지가 필요할 때마다 스토어에서 매번 조회했다. 새 VM에서는 한 번 로딩된 패키지를 최대 200개까지 메모리에 캐싱하고, 타입 오리진 매핑(어떤 타입이 어떤 패키지에서 처음 정의되었는지)도 별도로 1,000개까지 캐싱한다. 트랜잭션이 여러 패키지에 걸쳐 함수를 호출하는 경우, 같은 패키지를 반복해서 로딩할 필요가 없어진다.
얼핏 단순한 최적화처럼 보이지만, 수이의 실행 모델을 생각하면 임팩트가 크다. 수이에서 하나의 PTB는 여러 개의 Move 함수 호출을 체이닝할 수 있고, 디파이 프로토콜의 경우 하나의 트랜잭션 안에서 DEX, 렌딩, 오라클 등 서로 다른 패키지의 함수를 연속적으로 호출하는 것이 일반적이다. 패키지 캐싱은 이런 복합 트랜잭션의 실행 시간을 실질적으로 줄여준다.
다만, 현재의 CachedPackageStore는 과도기적 구현이다. 코드 내 주석에는 "향후 대부분 또는 전부가 새 VM의 런타임 캐시로 대체될 것"이라고 명시되어 있다. 실제로 Move VM 런타임 레이어에는 이미 MoveCache라는 별도의 캐시 구조가 존재하며, DashMap 기반의 동시성 지원 패키지 캐시와 링키지별 VTable 캐시를 갖추고 있다. 현재 Sui 어댑터 레벨의 CachedPackageStore가 담당하는 역할이 점차 VM 내부로 흡수되면, 캐싱이 실행 엔진 깊숙한 곳에서 이루어지게 되어 더 큰 성능 이점을 기대할 수 있다.
코드 레벨에서 흥미로운 부분은 v3의 Move VM 인터프리터에 추가된 새로운 바이트코드 명령어들이다.
이들은 Move 언어에서 enum(열거형)을 지원하기 위한 명령어들이다. 기존 Move에서는 struct만 사용할 수 있었기 때문에, 여러 가지 상태를 표현하려면 별도의 모듈 패턴을 사용해야 했다. enum이 도입되면 패턴 매칭이 가능해지고, 스마트 컨트랙트의 상태 머신을 훨씬 자연스럽게 표현할 수 있게 된다.
바이트코드 검증기에도 ability_cache.rs, data_defs.rs, regex_reference_safety/ 등의 새 모듈이 추가되었다. 이는 단순히 enum 하나를 위한 것이 아니라, Move 타입 시스템 전체가 한 단계 확장되고 있다는 뜻으로, 수이 팀은 기존 아키텍처로는 지원하기 어려웠던 차세대 Move 기능의 기반을 마련한다고 언급하고 있다.
VM을 통째로 재작성한다는 것은 보안 관점에서 상당한 리스크를 수반한다. 실행 계층은 블록체인의 핵심 중의 핵심이기 때문에, 여기서 발생하는 취약점은 곧바로 자산 손실이나 네트워크 장애로 이어질 수 있다.
수이 측은 이 리스크를 정면으로 인정하고 있다. 내부 리뷰와 OtterSec, Zellic의 독립 감사를 완료한 데 더해, 코드가 테스트넷에 올라가기도 전에 HackenProof에서 버그 바운티를 메인넷 보상 수준으로 열었다. 통상적으로 버그 바운티는 코드가 프로덕션에 가까워질수록 보상이 높아지는데, 아직 테스트넷 배포 전인 코드에 메인넷 요율을 적용한 것은 커뮤니티의 보안 리뷰를 최대한 이른 시점에 끌어오겠다는 의도로 읽힌다.
정적 타입 분석이 추가된 것 자체도 보안에 긍정적이다. 실행 전에 타입과 borrow 규칙을 검증하면, 런타임에서 예상치 못한 타입 혼동이나 레퍼런스 오용이 발생할 가능성이 줄어든다. 물론 정적 분석 코드 자체에 버그가 있을 수 있으므로 이를 충분히 검증하는 것이 선행되어야 하지만, 장기적으로는 실행 계층의 안전성을 구조적으로 높이는 방향이다.
수이의 새 VM의 메인넷 배포 목표는 4월 초다. 그 전까지 버그 바운티를 통해 커뮤니티의 충분한 검증이 이루어지길 기대하며, 이 업그레이드가 수이 실행 계층의 장기적인 확장성에 어떤 영향을 미칠지 지켜볼 필요가 있다.