
소프트웨어를 개발하는 목적은 그것이 의도한 대로 작동하도록 하는 것입니다. 이를 달성하려면 여러 번의 테스트 반복이 필요하며, 반복 간의 시간은 가능한 한 빨리 작업을 완료하려는 데 중요한 역할을 합니다.
Origin에서는 개발에 단위 테스트 및 포크 테스트를 사용합니다. 포크 테스트를 실행하는 것은 지루하게 느릴 수 있지만, 포크 테스트의 실행 시간을 (일부 경우에는) 4배로 줄일 수 있었습니다. 이 글을 통해 포크 테스트의 속도를 향상시킬 수 있는 방법에 대해 설명하겠습니다. 이렇게 하면 의도한 대로 코드를 빠르게 작동시킬 수 있습니다.
일반적으로 포크 테스트 또는 단위 테스트를 사용할지는 개발 중인 프로토콜의 아키텍처에 따라 다릅니다. 어떤 팀은 단위 테스트만 사용하고 어떤 팀은 단위 및 포크 테스트를 모두 사용합니다. Origin에서는 계약이 여러 제3자 프로토콜(Curve, Uniswap, Balancer, Convex 등)과 상호 작용하며 통합 오류가 재앙적인 자금 손실을 일으킬 수 있는 경우가 있어서입니다.
단위 테스트를 사용하여 제3자 프로토콜의 ABI를 모의하고 계약이 프로그래밍적으로 올바르게 통합되는지 테스트합니다. 그러나 제3자 프로토콜의 동작을 모든 복잡성과 프로토콜이 가질 수 있는 다양한 (합법적 또는 조작된) 상태로 테스트하는 것이 바로 포크 테스트의 강점입니다. 그리고 팀의 일부 엔지니어에게는 포크 테스트를 사용한 테스트 주도 개발이 주요 개발 모드입니다. "코드 변경"에서 "테스트 실행"까지 걸리는 시간을 줄이는 것이 중요합니다.
Origin에서는 Solidity 개발 스택으로 Hardhat을 사용하고 있습니다. 개발 주기 시간을 단축하기 위해 포크 테스트 실행의 다양한 단계를 이해하는 것이 중요합니다. 간편하게, 한 번에 1개의 포크 테스트만 실행할 것이며, 이는 스마트 계약 작업 시 일반적으로 채택되는 방식입니다.
이러한 각 단계를 이해하고 최적화하는 것은 Origin에서 효율적인 포크 테스트 개발 주기에 기여합니다.
가장 느린 접근 방식은 노드를 최신 블록에서 포크하여 포크 테스트를 실행하는 것입니다. 이 방식으로 테스트를 실행할 때마다 다른 블록 높이가 선택되며, hardhat은 메인넷 프로바이더에서 스토리지 슬롯을 읽어와 캐싱을 수행할 수 없습니다. 이로 인해 실행 속도가 느린 101초가 나옵니다.

이 특정 포크 테스트는 자금을 당사의 유동성 마이닝 전략 중 하나에 전송합니다. 이 전략은 자산을 Balancer 풀에 배포합니다. 이로 인해 많은 양의 스토리지 슬롯 읽기가 발생하며 실행의 느린 "테스트" 부분(위의 막대의 주황색 부분)의 주된 원인이 됩니다.
명백한 저매매 열매는 블록 높이를 수정하여 Hardhat이 스토리지 슬롯 읽기의 로컬 캐시를 활용함으로써 시간을 상당히 절약할 수 있도록 하는 것입니다. 이 최적화는 컴파일 시간에는 영향을 미치지 않지만 다른 모든 단계에 영향을 미칩니다. 주기 시간을 27초로 크게 줄이게 됩니다 (이는 테스트의 첫 실행이 아닌 경우에 해당하며, 이때에는 hardhat 캐시가 이미 웜업된 상태입니다).

위의 방법은 상황을 크게 개선하지만, 여전히 단위 테스트의 속도에서는 멀리 떨어져 있으며 때때로 괴롭힘을 줄 수 있습니다. 우리는 단 하나의 계약만 변경했습니다. 왜 이제 IDEALLY 1개 또는 그 이상의 Solidity 계약의 바이트 코드만 변경하면 되는 상황에서 동일한 배포와 배포 후 실행을 다시 실행해야 할까요? 물론 컴파일 간에 스토리지 슬롯 레이아웃이나 상태를 변경하지 않는다면요. 이 때 hot deploys가 등장합니다.
핫 디플로이는 수정 중인 계약을 배포하고 해당 계약의 바이트 코드를 가져옵니다. Hardhat 테스트 스위트 스냅샷을 사용하여 테스트가 실행되기 전의 해당 계약의 이전 버전을 찾고 그 바이트 코드를 새로 컴파일된 것으로 대체합니다. 더불어 테스트 픽스처와 테스트 자체를 실행하며 모든 (포스트) 배포 단계를 건너뛰게 됩니다.

이제 주기 시간이 단 7초로 줄었습니다. 개발 주기의 이 변경으로 Origin Protocol은 크게 생산성을 향상시키고 기능을 개발할 수 있는 속도를 높일 수 있었습니다.
안타깝게도 핫 디플로이는 스위치처럼 간단히 켜고 끌 수 있는 것이 아니며(적어도 아직은), 일부 구성이 필요합니다. Origin에서 이 해결책을 구현한 방식은 다음과 같습니다:
중요한 요구 사항 중 하나는 포크 테스트 환경과 별도로 동작 중인 독립형 hardhat 노드가 있어야 한다는 것입니다. 즉시 명확하지 않을 수 있지만, 포크 테스트 실행은 다른 노드 런타임을 생성하고 독립적으로 실행 중인 노드를 프로바이더로 사용합니다. 독립형 노드는 모든 (포스트) 배포를 실행하고, 포크 테스트 노드는 변경 사항을 컴파일하고 필요한 모든 계약 바이트 코드를 대체하는 테스트 픽스처를 실행하고, 마지막으로 테스트를 실행합니다.
배포 파일, 계약 스토리지 슬롯 및 그들의 상태 설정에 대한 변경 사항을 염두에 두는 것이 좋습니다. 테스트 픽스처를 실행하려면 독립형 노드를 다시 시작해야 한다는 점도 고려해야 합니다.
가끔은 우리는 개발을 빠르게 진행할 수 있는 유닛 테스트를 사용하고, 이는 3rd 파티 프로토콜과 통합되는 플랫폼 부분에 대해 포크 테스트가 제공하는 추가적인 보안 비용을 감수하고자 할 수 있습니다. Origin의 개발자들에게는 핫 디플로이가 그 주기 시간 간극을 메우기 위한 중요한 단계이며, 동시에 더 나은 보안을 제공하려는 시도입니다. 다른 이들도 이를 시도해보기를 바라며, 이 접근 방식을 통해 개발 주기 시간을 단축하는 데 도움이 되기를 기대합니다.
