infrablockchain-docs
ko
ko
  • 인프라블록체인
    • 배우기
      • 아키텍처
        • 아키텍처
        • 네트워크 참여자
        • 파라체인
          • 시스템 파라체인
      • 프로토콜
        • 시스템 토큰
        • 트랜잭션 수수료
        • Proof of Transaction
      • Substrate
        • 배우기
          • 기초 지식
            • 암호학
            • 블록체인 기본 개념
            • 합의
            • 네트워크와 노드
            • 트랜잭션과 블록 기본 사항
            • 트랜잭션 수명주기
            • 오프체인 작업
            • 라이트 클라이언트
            • Substrate를 위한 Rust
            • 라이브러리 소개
            • 아키텍처와 Rust 라이브러리
            • 파일 구조
            • 계정, 주소 및 키
            • 트랜잭션 형식
            • 난수 생성
          • 프레임
            • FRAME 팔레트
            • FRAME 매크로
            • 커스텀 팔레트
            • 팔레트 커플링
            • Origin
            • 이벤트와 에러
            • 런타임 스토리지 구조
            • 상태 전이와 스토리지
            • SCALE 인코딩
            • 트랜잭션, Weight 및 수수료
            • 런타임 API
            • 런타임 업그레이드
            • 런타임 개발
          • 계정 데이터 구조
          • 주소 형식
          • 용어집
          • cli
            • 아카이브
            • 메모리 프로파일러
            • 노드 템플릿
            • 사이드카
            • srtool
            • 서브키
            • subxt
            • try-runtime
            • tx-wrapper
          • 런타임 개발
            • 기본
              • Genesis 상태 구성하기
              • 런타임 상수 구성
              • 체인 스펙을 커스텀하기
              • 팔레트 가져오기
              • 도우미 함수 사용하기
            • 합의 모델
              • 작업 증명을 사용하는 체인 구성
              • 하이브리드 노드 생성하기
            • 오프체인 워커
              • 오프체인 HTTP 요청하기
              • 오프체인 인덱싱
              • 오프체인 로컬 스토리지
            • 팔레트 설계
              • 크라우드펀딩 구성하기
              • 스토리지 구조체 (struct) 생성하기
              • 잠금 가능한 통화 구현
              • 무작위성 적용하기
              • 느슨한 팔레트 결합 사용하기
              • 타이트한 팔레트 결합 사용하기
            • 파라체인 개발
              • HRMP 채널 추가하기
              • 로컬 파라체인 노드 추가하기
              • 릴레이 체인에 연결하기
              • 솔로 체인을 변환하기
              • 론칭 준비
              • 콜레이터 선택
              • 파라체인 업그레이드
            • 스토리지 마이그레이션
              • 기본 저장소 마이그레이션
              • 스토리지 마이그레이션 트리거
            • 테스트
              • 기본 테스트 설정하기
              • 전송 함수 테스트하기
            • 도구
              • 체인을 위한 txwrapper 생성
              • REST 엔드포인트를 사용하여 체인 데이터 가져오기
              • try-runtime 사용하기
              • Wasm 바이너리 검증하기
            • 가중치
              • 벤치마크 추가
              • 수수료 계산하기
              • 조건부 가중치 사용
              • 사용자 정의 가중치 사용하기
        • 빌드하기
          • 제작할 것을 결정하세요
          • 빌드 프로세스
          • 결정론적 런타임 빌드
          • 체인 스펙
          • Genesis 구성
          • 애플리케이션 개발
          • RPC
          • 문제 해결
        • 튜토리얼
          • 설치하기
            • 개발자 도구
            • 리눅스 개발 환경
            • macOS 개발 환경
            • Rust 툴체인
            • Rust 문제 해결 방법
            • Windows 개발 환경
          • 빠른 시작
            • 코드 탐색하기
            • 런타임 수정하기
            • 노드 시작하기
            • Substrate 한눈에 보기
          • 블록체인 구축
            • 신뢰할 수 있는 노드 추가
            • 특정 노드 승인
            • 로컬 블록체인 구축하기
            • 네트워크 시뮬레이션
            • 실행 중인 네트워크 업그레이드
          • 애플리케이션 로직 구축
            • 런타임에 팔레트 추가하기
            • 오프체인 워커 추가
            • 사용자 정의 팔레트 게시
            • 함수 호출의 출처 지정하기
            • 사용자 정의 팔레트에서 매크로 사용하기
          • 유용한 도구들
            • EVM 계정에 접근하기
            • 이더리움 통합
            • 사이드카 엔드포인트 탐색하기
            • 경량 클라이언트 노드 통합
          • 스마트 컨트랙트
            • 스마트 컨트랙트
            • 토큰 계약 작성하기
            • 스마트 컨트랙트 개발하기
            • 첫 번째 계약 준비하기
            • 스마트 컨트랙트 문제 해결
            • 값 저장을 위한 맵 사용
      • XCM
        • XCM
        • XCM 형식
    • 서비스 체인
      • 인프라DID
      • 인프라EVM
      • URAuth(Universal Resource Auth)
    • 데브 옵스
      • 체인 빌드
      • 배포
      • 모니터링
    • 튜토리얼
      • 기초
        • 시스템 토큰 관리 프로세스
        • 시스템 토큰을 트랜잭션 수수료로 사용해보기
        • 트랜잭션에 투표 포함 시키기
        • 밸리데이터 보상 받기
      • 구축하기
        • 인프라릴레이체인 구축하기
        • 파라체인 구축하기
        • 메시지 전달 채널 열기
        • XCM을 이용하여 토큰 전송하기
        • Asynchronous Backing 적용하기
      • 테스트
        • 벤치마크
        • 런타임 확인
        • 디버그
        • 테스트 네트워크에서 파라체인 시뮬레이션하기
        • 단위 테스트
      • 서비스체인
        • 인프라DID
          • 구축하기
          • 공개키 추가하기
          • 서비스 엔드포인트 등록하기
          • DID 생성하기
        • 인프라EVM
          • 구축하기
          • EVM에 자금 입금 및 인출하기
          • ERC20 토큰 컨트랙트 배포하기
          • ERC721 토큰 컨트랙트 배포하기
          • ERC1155 토큰 컨트랙트 배포하기
  • 뉴날 데이터 마켓
Powered by GitBook
On this page
  • 팔렛에 대한 벤치마크의 필요성
  • 선형 모델 개발
  • 벤치마킹과 가중치
  • 벤치마킹 도구
  • 벤치마크 작성
  • 벤치마크 테스트
  • 벤치마크 추가
  • 벤치마크 실행
  • 다음 단계로 넘어가기
  1. 인프라블록체인
  2. 튜토리얼
  3. 테스트

벤치마크

런타임 로직의 함수를 실행하는 데 필요한 계산 리소스를 추정하기 위해 사용할 수 있는 벤치마킹 프레임워크를 설명합니다.

Previous테스트Next런타임 확인

Last updated 1 year ago

Substrate와 FRAME은 블록체인에 대한 사용자 정의 로직을 개발하기 위한 유연한 프레임워크를 제공합니다. 이 유연성은 복잡하고 상호작용하는 팔렛을 설계하고 정교한 런타임 로직을 구현할 수 있도록 합니다. 그러나 팔렛의 함수에 할당할 적절한 를 결정하는 것은 어려운 작업일 수 있습니다. 벤치마킹을 사용하면 런타임에서 다른 조건에서 다른 함수를 실행하는 데 걸리는 시간을 측정할 수 있습니다. 벤치마킹을 사용하여 함수 호출에 정확한 가중치를 할당하면, 악의적인 사용자에 의한 블록체인의 과부하로 인해 블록을 생성하지 못하거나 서비스 거부(DoS) 공격에 취약해지는 것을 방지할 수 있습니다.

팔렛에 대한 벤치마크의 필요성

다른 함수를 실행하는 데 필요한 계산 리소스, 런타임 함수인 on_initialize 및 verify_unsigned를 포함하여 이해하는 것은 런타임의 안전성을 유지하고 리소스가 있는 경우에만 트랜잭션을 포함하거나 제외할 수 있도록 하는 데 중요합니다.

리소스가 있는 경우 트랜잭션을 포함하거나 제외할 수 있는 능력은 런타임이 서비스 중단 없이 블록을 계속 생성하고 가져올 수 있도록 합니다. 예를 들어, 특히 집중적인 계산을 필요로 하는 함수 호출이 있는 경우, 해당 호출을 실행하는 데 걸리는 시간이 블록 생성 또는 가져오기에 허용된 최대 시간을 초과할 수 있으므로 블록 처리 과정을 방해하거나 블록체인의 진행을 중지시킬 수 있습니다. 벤치마킹을 통해 다른 함수에 필요한 실행 시간이 합리적인 범위 내에 있는지 확인할 수 있습니다.

마찬가지로, 악의적인 사용자는 집중적인 계산을 필요로 하는 함수 호출을 반복적으로 실행하거나 필요한 계산을 정확하게 반영하지 않는 함수 호출을 실행하여 네트워크 서비스를 방해하려고 할 수 있습니다. 함수 호출을 실행하는 데 필요한 비용이 계산에 정확하게 반영되지 않는 경우, 악의적인 사용자가 네트워크를 공격하는 것을 방지할 동기가 없습니다. 벤치마킹을 통해 트랜잭션 실행에 연관된 가중치를 평가할 수 있으므로, 적절한 트랜잭션 수수료를 결정하는 데도 도움이 됩니다. 벤치마크를 기반으로 트랜잭션 실행에 소비되는 리소스를 나타내는 수수료를 설정할 수 있습니다.

선형 모델 개발

벤치마킹은 다음 단계를 수행해야 합니다:

  • 특정 함수에 대한 특정 코드 경로를 실행하는 사용자 정의 벤치마킹 로직을 작성합니다.

  • 특정 하드웨어 및 특정 런타임 구성을 사용하여 WebAssembly 실행 환경에서 벤치마킹 로직을 실행합니다.

  • 함수 실행에 영향을 미칠 수 있는 가능한 값의 제어 범위에서 벤치마킹 로직을 실행합니다.

  • 함수의 각 구성 요소에 대해 벤치마크를 여러 번 실행하여 이상치를 분리하고 제거합니다.

벤치마킹 로직을 실행하여 생성된 결과를 통해 벤치마킹 도구는 함수의 선형 모델을 생성합니다. 함수에 대한 선형 모델을 사용하면 특정 코드 경로를 실행하는 데 걸리는 시간을 추정하고 실제로 런타임에서 상당한 리소스를 소비하지 않고도 정보를 기반으로 결정할 수 있습니다. 벤치마킹은 모든 트랜잭션이 선형 복잡성을 가진다고 가정합니다. 더 높은 복잡성을 가진 함수는 런타임 상태나 입력이 너무 복잡해지면 이러한 함수의 가중치가 폭발할 수 있기 때문에 런타임에 위험하다고 간주됩니다.

벤치마킹과 가중치

에서 설명한 대로, Substrate 기반 체인은 블록의 트랜잭션을 실행하는 데 걸리는 시간을 나타내는 가중치 개념을 사용합니다. 특정 호출을 실행하는 데 필요한 시간은 다음과 같은 여러 요소에 따라 달라집니다.

  • 계산 복잡성

  • 저장소 복잡성

  • 필요한 데이터베이스 읽기 및 쓰기 작업

  • 사용된 하드웨어

트랜잭션에 적절한 가중치를 계산하려면, 벤치마크 매개변수를 사용하여 다른 하드웨어에서 다른 변수 값 및 여러 번 반복하여 함수 호출을 실행하는 데 걸리는 시간을 측정할 수 있습니다. 그런 다음 벤치마킹 테스트의 결과를 사용하여 각 함수 호출 및 각 코드 경로를 실행하는 데 필요한 리소스를 나타내는 근사적인 최악의 경우 가중치를 설정할 수 있습니다. 수수료는 최악의 경우 가중치를 기반으로 합니다. 실제 호출이 최악의 경우보다 성능이 우수한 경우, 가중치가 조정되고 초과 수수료가 반환될 수 있습니다.

가중치는 특정 물리적인 기계의 계산 시간을 기반으로 하는 일반적인 측정 단위이므로, 벤치마킹에 사용된 특정 하드웨어에 따라 함수의 가중치가 변경될 수 있습니다.

각 런타임 함수의 예상 가중치를 모델링함으로써 블록체인은 일정 기간 동안 얼마나 많은 트랜잭션 또는 시스템 수준 호출을 실행할 수 있는지 계산할 수 있습니다.

FRAME 내에서 디스패치할 수 있는 각 함수 호출은 해당 함수의 #[weight] 주석을 가져야 합니다. 벤치마킹 프레임워크는 이러한 공식을 자동으로 생성하는 파일을 생성합니다.

벤치마킹 도구

노드를 컴파일할 때 벤치마킹 파이프라인은 기본적으로 비활성화됩니다. 벤치마크를 실행하려면 runtime-benchmarks Rust 기능 플래그를 사용하여 노드를 컴파일해야 합니다.

벤치마크 작성

런타임 벤치마크를 작성하는 것은 팔렛의 단위 테스트를 작성하는 것과 유사합니다. 단위 테스트와 마찬가지로 벤치마크는 코드의 특정 논리적 경로를 실행해야 합니다. 단위 테스트에서는 코드를 특정 성공 및 실패 결과에 대해 확인합니다. 벤치마크에서는 가장 계산적으로 집중적인 경로를 실행하려고 합니다.

벤치마크를 작성할 때 함수의 복잡성에 영향을 줄 수 있는 특정 조건 (예: 저장소 또는 런타임 상태)을 고려해야 합니다. 예를 들어, for 루프에서 더 많은 반복을 트리거하는 경우 데이터베이스 읽기 및 쓰기 작업의 수가 증가할 수 있으므로, 이 조건을 트리거하는 벤치마크를 설정하여 함수의 성능을 더 정확하게 나타낼 수 있습니다.

함수가 사용자 입력이나 다른 조건에 따라 다른 코드 경로를 실행하는 경우, 가장 계산적으로 집중적인 경로가 어떤 것인지 알 수 없을 수 있습니다. 코드의 복잡성이 관리하기 어려워질 수 있는 위치를 파악하기 위해 각 가능한 실행 경로에 대한 벤치마크를 생성해야 합니다. 벤치마크를 사용하여 사용자가 팔렛과 상호작용하는 방식을 제어하기 위해 벡터의 요소 수를 제한하거나 for 루프의 반복 횟수를 제한하는 등의 경계를 강제하는 코드의 위치를 식별할 수 있습니다.

벤치마크 테스트

팔렛을 단위 테스트하는 데 사용한 것과 동일한 모의 런타임을 사용하여 벤치마크를 테스트할 수 있습니다. benchmarking.rs 모듈에서 사용하는 벤치마크 매크로는 자동으로 테스트 함수를 생성합니다. 예를 들어:

fn test_benchmark_[벤치마크_이름]<T>::() -> Result<(), &'static str>

벤치마크 함수를 단위 테스트에 추가하고 함수의 결과가 Ok(())인지 확인할 수 있습니다.

블록 확인

일반적으로 벤치마크가 Ok(())를 반환했는지만 확인하면 됩니다. 이 결과는 함수가 성공적으로 실행되었음을 나타냅니다. 그러나 벤치마크에 최종 상태와 같은 최종 조건을 확인하려는 경우 verify 블록을 선택적으로 포함할 수 있습니다. 추가 verify 블록은 최종 벤치마킹 프로세스의 결과에 영향을 주지 않습니다.

벤치마크가 포함된 단위 테스트 실행

벤치마킹 테스트를 실행하려면 테스트할 패키지를 지정하고 runtime-benchmarks 기능을 활성화해야 합니다. 예를 들어, 다음 명령을 실행하여 Balances 팔렛에 대한 벤치마크를 테스트할 수 있습니다.

cargo test --package pallet-balances --features runtime-benchmarks

벤치마크 추가

이미 노드에 일부 벤치마크가 설정되어 있는 경우, 팔렛을 define_benchmarks! 매크로에 추가하기만 하면 됩니다.

#[cfg(feature = "runtime-benchmarks")]
mod benches {
	define_benchmarks!(
		[frame_benchmarking, BaselineBench::<Runtime>]
		[pallet_assets, Assets]
		[pallet_babe, Babe]
    ...
    [pallet_mycustom, MyCustom]
    ...

팔렛을 추가한 후에는 runtime-benchmarks 기능 플래그를 사용하여 노드 바이너리를 컴파일합니다. 예를 들어:

cd bin/node/cli
cargo build --profile=production --features runtime-benchmarks

production 프로필은 다양한 컴파일러 최적화를 적용합니다. 이러한 최적화는 컴파일 프로세스를 매우 느리게 만듭니다. 테스트 중이고 최종 숫자가 필요하지 않은 경우, production 프로필 대신 --release 커맨드 라인 옵션을 사용하십시오.

벤치마크 실행

벤치마크가 활성화된 노드 바이너리를 컴파일한 후에는 벤치마크를 실행해야 합니다. 노드를 컴파일할 때 production 프로필을 사용한 경우, 다음 명령을 실행하여 사용 가능한 벤치마크를 나열할 수 있습니다.

./target/production/node-template benchmark pallet --list

모든 팔렛의 모든 함수에 대한 벤치마크 실행

런타임의 모든 벤치마크를 실행하려면 다음과 유사한 명령을 실행할 수 있습니다.

./target/production/node-template benchmark pallet \
    --chain dev \
    --execution=wasm \
    --wasm-execution=compiled \
    --pallet "*" \
    --extrinsic "*" \
    --steps 50 \
    --repeat 20 \
    --output pallets/all-weight.rs

이 명령은 all-weight.rs라는 파일을 생성하여 런타임에 대한 WeightInfo 트레이트를 구현합니다.

특정 팔렛의 특정 함수에 대한 벤치마크 실행

특정 팔렛의 특정 함수에 대한 벤치마크를 실행하려면 다음과 유사한 명령을 실행할 수 있습니다.

./target/production/node-template benchmark pallet \
    --chain dev \
    --execution=wasm \
    --wasm-execution=compiled \
    --pallet pallet_balances \
    --extrinsic transfer \
    --steps 50 \
    --repeat 20 \
    --output pallets/transfer-weight.rs

이 명령은 pallet_balances 팔렛을 위한 transfer-weight.rs와 같은 선택한 팔렛을 위한 출력 파일을 생성하며, WeightInfo 트레이트를 구현합니다.

템플릿을 사용하여 벤치마크 서식 지정

벤치마크 명령줄 인터페이스는 최종 출력 파일을 서식 지정하기 위해 Handlebars 템플릿을 사용합니다. 기본값 대신 사용자 정의 템플릿을 지정하려면 --template 명령줄 옵션을 선택적으로 전달할 수 있습니다. 템플릿 내에서는 벤치마킹 명령줄 인터페이스의 TemplateData 구조체에서 제공하는 모든 데이터에 액세스할 수 있습니다.

출력 생성에 포함된 몇 가지 사용자 정의 Handlebars 도우미가 있습니다.

  • underscore: 문자열의 오른쪽에서부터 3자리마다 밑줄을 추가합니다. 주로 큰 숫자를 구분하기 위해 사용됩니다.

  • join: 문자열 배열을 템플릿에 공백으로 구분된 문자열로 결합합니다. 주로 CLI에 전달된 모든 인수를 결합하는 데 사용됩니다.

benchmark 하위 명령어의 전체 목록을 보려면 다음을 실행합니다.

./target/production/node-template benchmark --help

benchmark pallet 하위 명령어의 사용 가능한 옵션 목록을 보려면 다음을 실행합니다.

./target/production/node-template benchmark pallet --help

다음 단계로 넘어가기

는 런타임의 함수에 대한 벤치마크를 추가, 테스트, 실행 및 분석하는 데 도움이 되는 도구를 제공합니다. 함수 호출을 실행하는 데 걸리는 시간을 결정하는 데 도움이 되는 벤치마킹 도구는 다음과 같습니다.

는 런타임 벤치마크를 작성, 테스트 및 추가하는 데 도움이 됩니다.

는 벤치마크 데이터를 처리하는 데 사용됩니다.

를 사용하여 노드에서 벤치마크를 실행할 수 있습니다.

모든 미리 구축된 에서 종단간 벤치마크 예제를 찾을 수 있습니다.

각 팔렛에 포함된 벤치마크는 자동으로 노드에 추가되지 않습니다. 이러한 벤치마크를 실행하려면 frame_benchmarking::Benchmark 트레이트를 구현해야 합니다. 이를 수행하는 방법에 대한 예제는 에서 확인할 수 있습니다.

벤치마킹 프레임워크
벤치마크 매크로
선형 회귀 분석 함수
Command-line interface (CLI)
FRAME 팔렛
Substrate 노드
프레임 벤치마킹(Frame-benchmarking)
Substrate 세미나: Substrate 팔렛의 벤치마킹
벤치마크 추가하는 법
트랜잭션, 가중치 및 수수료
가중치
Command reference: 노드 템플릿 벤치마크