본문으로 건너뛰기

릴리스 노트


v1.70.2

🔶 Testnet | Source: GitHub Release

Sui Protocol Version in this release: 121

#26095: 120을 121로 올리고, jump 주변의 cleanliness를 강제하기 위한 추가 check를 120에 추가한다.

#23295: Move standard library function std::u8::mul_div를 추가한다. Move standard library function std::u8::mul_div_ceil을 추가한다. Move standard library function std::u16::mul_div를 추가한다. Move standard library function std::u16::mul_div_ceil을 추가한다. Move standard library function std::u32::mul_div를 추가한다. Move standard library function std::u32::mul_div_ceil을 추가한다. Move standard library function std::u64::mul_div를 추가한다. Move standard library function std::u64::mul_div_ceil을 추가한다. Move standard library function std::u128::mul_div를 추가한다. Move standard library function std::u128::mul_div_ceil을 추가한다. Move standard library function std::u256::mul_div를 추가한다. Move standard library function std::u256::mul_div_ceil을 추가한다.

#26051: std::u8::divide_and_round_upstd::u8::div_ceil로 대체하기 위해 deprecated 처리한다. std::u16::divide_and_round_upstd::u16::div_ceil로 대체하기 위해 deprecated 처리한다. std::u32::divide_and_round_upstd::u32::div_ceil로 대체하기 위해 deprecated 처리한다. std::u64::divide_and_round_upstd::u64::div_ceil로 대체하기 위해 deprecated 처리한다. std::u128::divide_and_round_upstd::u128::div_ceil로 대체하기 위해 deprecated 처리한다. std::u256::divide_and_round_upstd::u256::div_ceil로 대체하기 위해 deprecated 처리한다.

gRPC

#26070: structured output에 0x1::type_name::TypeName Move value가 나타나면, name field가 있는 object가 아니라 type의 단순 string representation으로 표시된다.

#26062: Display v2: str transform이 동작하지 않는 field는 json transform을 사용해 암묵적으로 format한다.

JSON-RPC

#26070: structured output에 0x1::type_name::TypeName Move value가 나타나면, name field가 있는 object가 아니라 type의 단순 string representation으로 표시된다.

#26062: Display v2: str transform이 동작하지 않는 field는 json transform을 사용해 암묵적으로 format한다.

GraphQL

#26061: GraphQL이 Display v2 format을 fetch하는 방식의 bugfix.

#26070: structured output에 0x1::type_name::TypeName Move value가 나타나면, name field가 있는 object가 아니라 type의 단순 string representation으로 표시된다.

#26062: Display v2: str transform이 동작하지 않는 field는 json transform을 사용해 암묵적으로 format한다.

Indexing Framework

#25881: Connection trait를 ConcurrentConnection/SequentialConnection subtrait로, Store trait를 ConcurrentStore/SequentialStore subtrait로 refactor한다.

#26092: 최근 refactoring에서 도입되었지만 사용되지 않는 SequentialStore::sequential_connect를 제거한다.

#26133: backward indexing을 지원하기 위해 ObjectStoreConnectionConcurrentConnection을 구현한다.

#26096: CheckpointData::Raw raw variant를 제거한다. 모든 ingestion error를 transient(retryable)로 처리한다. gRPC ingestion 중 total_ingested_bytes를 채운다.

#26116: IngestionClientTrait::latest_checkpoint_number()를 추가했으며, pruning이 활성화된 concurrent pipeline은 이제 network tip - retention에서 indexing을 시작한다.


Full Log: https://github.com/MystenLabs/sui/commits/testnet-v1.70.2

v1.69.2

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 120

#26098: protocol version 120에 jump 주변의 cleanliness를 강제하기 위한 추가 check를 추가한다.

#25792: Sui System의 metadata hardening.

#25838: protocol version 118에서 새 Move VM을 활성화한다.

#25911: cherry-pick 때문에 새 VM이 118 대신 119로 밀렸다.

gRPC

#25908: X_SUI_CHAIN_ID header가 전체 32-byte, base58 encoded chain id를 반환하도록 수정한다.

#25828: archival을 위해 balance changes와 object set을 연결한다.

#26112: Display v2: str transform이 동작하지 않는 field는 json transform을 사용해 암묵적으로 format한다.

JSON-RPC

#26112: Display v2: str transform이 동작하지 않는 field는 json transform을 사용해 암묵적으로 format한다.

GraphQL

#26112: Display v2: str transform이 동작하지 않는 field는 json transform을 사용해 암묵적으로 format한다.

CLI

#25862: sui client object가 이제 raw BCS-encoded byte array 대신 decoded Move struct field를 표시한다.

#25444: tree shaking이 비활성화된 경우 active network connection 없이도 sui move build --dump를 실행할 수 있다.

Windows에서 local dependency가 있는 ephemeral publication 관련 fix.

undefined environment를 대상으로 build할 때 error message를 개선했다.

Indexing Framework

#25838: mocks/store.rs의 clippy lint를 수정한다.

Co-authored-by: @cgswords

#25834: IngestionClientTrait::fetchIngestionClientTrait::checkpoint로 rename했다.

#25895: ingestion source에서 chain_id를 가져오기 위해 새 IngestionClientTrait::chain_id를 추가한다.

#25905: Processor의 receiver가 chain_id를 포함하는 새 CheckpointEnvelope type을 받도록 변경했다.

#25875: chain_id를 저장하고 가져오는 Connection::init_chain_id method를 추가한다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.69.2

v1.68.1

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 118

#25907: display migration cap에 누락된 function을 추가한다.

#25674: mainnet에서 address aliases feature를 활성화한다.

#23710: Display V2를 활성화한다(0xd system object가 생성됨).

#25827: Sui System의 metadata hardening.

노드(검증자 및 풀 노드)

#25624: invalid funds withdrawals가 있는 malformed transaction을 simulate할 때 fullnode panic이 발생할 수 있는 문제를 수정한다.

JSON-RPC

#25360: JSONRPC에 Display Registry 지원을 추가한다. showDisplay가 설정되면 RPC는 Display Registry에 저장된 Display<T>를 찾고 이를 해당 type format의 source of truth로 사용한다. 이는 이 type에 존재하는 모든 Display v1 format보다 우선한다.

GraphQL

#25479: Move Values의 vector를 paginate하기 위한 MoveValue.asVector를 도입한다.

#25657: UserSignature용 새 union SignatureScheme을 도입한다.

#25715: ZkLoginVerifyResult는 더 이상 error를 포함하지 않는다. Error는 GraphQL response error의 일부가 아니다.

#25242: GraphQL에 Display Registry 지원을 추가한다. MoveValue.display는 Display Registry에 저장된 Display<T>를 찾고 이를 해당 type format의 source of truth로 사용한다. 이는 이 type에 존재하는 모든 Display v1 format보다 우선한다.

Indexing Framework

#25641: Processor concurrency(fanout)와 ingestion concurrency(ingest_concurrency)는 이제 기본적으로 adaptive concurrency control을 사용한다. 고정 worker 수 대신 concurrency는 1에서 시작해 downstream channel backpressure에 따라 자동으로 scale된다. 한도는 processor의 경우 num_cpus, ingestion의 경우 500이다.

Breaking changes:

  • Processor::FANOUT trait constant가 제거되었다. Processor concurrency는 이제 usize 대신 ConcurrencyConfig enum을 받는 ConcurrentConfig / SequentialConfigfanout field로 구성한다.
  • IngestionConfigingest_concurrencyusize에서 ConcurrencyConfig로 변경되었다.
  • processor와 downstream stage 사이 channel을 제어하는 새 processor_channel_size field가 추가되었다(기본값은 num_cpus / 2). 이전에는 이 channel 크기가 FANOUT + PIPELINE_BUFFER에서 자체적으로 결정되었다.

Migration: 이전 fixed-concurrency behavior를 유지하려면 fanout: Some(ConcurrencyConfig::Fixed { value: N }) 또는 ingest_concurrency: ConcurrencyConfig::Fixed { value: N }을 설정한다. 그렇지 않으면 변경이 필요 없다. adaptive default는 대부분의 workload에서 잘 동작해야 한다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.68.1

v1.67.3

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 115

#25795: VM 내부 일부 structure의 representation을 normalize하기 위해 새 protocol version 115를 추가한다.

#25556: mainnet에서 address aliases feature를 활성화한다.

#25585: execution의 일부 refactoring을 지원하기 위해 새 protocol version을 추가한다.

#25364: test 전용 변경으로, 사용자 영향은 없다.

GraphQL

#25261: simulateResultExecutionResult에서는 더 이상 Error field를 사용할 수 없다. 이는 GraphQL errors로 전파된다.

CLI

#25074: sui move build --dump(--dump-bytecode-as-base64의 짧은 version)가 이제 0 address가 포함된 bytecode를 올바르게 출력한다.

#25587: sui client ptb output의 pretty printing을 다시 활성화하는 bug를 수정했다.

Indexing Framework

#25434: ingestion client가 여러 source를 구성하도록 허용했지만 implicit precedence order에 따라 하나를 제외한 모든 source가 무시되던 문제를 수정한다. 이제 정확히 하나의 source만 제공해야 한다.

#25593: ingestion concurrency와 channel size를 줄인다. 테스트 결과 16 cpu machine에서 bottleneck 없이 large checkpoint 처리 시 OOM issue를 제거하는 것으로 나타났다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.67.3

v1.66.2

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 113

#25588: protocol version을 올린다.

#25361: version 111에서 dev inspect, dry run, execution의 error를 transaction data check 관점에서 더 일관되고 동일하게 만든다.

#25321: devnet의 sui-framework에 Ristretto255 group operation을 추가한다.

노드(검증자 및 풀 노드)

#25257: bridge node에 multi-provider Ethereum RPC 지원을 추가한다.

운영자는 이제 중복성과 장애 허용성을 높이기 위해 quorum 기반 consensus와 함께 여러 Ethereum RPC endpoint를 구성할 수 있다.

새 optional YAML config field는 다음과 같으며, 이는 sui bridge config에 추가된다:

  • eth-rpc-urls(RPC URL 목록)
  • eth-rpc-quorum(quorum 크기, 기본값 1)
  • eth-health-check-interval-secs(health check interval, 기본값 300s)

기존 eth-rpc-url field는 이전 버전과의 호환성을 위해 계속 동작한다.

단일 URL이 구성되면 multi-provider layer는 quorum, health-check, locking 메커니즘 없이 zero-overhead passthrough로 동작한다.

gRPC

#25191: 새 BigTable schema와 pipeline별 watermark를 읽는다.

GraphQL

#25109: GraphQL에서 partial error를 올바르게 지원하며, 유효하지 않은 field에는 error message가 표시되고 유효한 field는 정상적으로 계속 표시된다.

#25110: GraphQL에서 partial error를 올바르게 지원하며, 유효하지 않은 field에는 error message가 표시되고 유효한 field는 정상적으로 계속 표시된다.

#25186: chainIdentifier query가 이제 Base58로 인코딩된 전체 32바이트 digest를 반환한다.

#24788: scanning API용 bloom filter pipeline을 추가한다.

#25191: 새 BigTable schema와 pipeline별 watermark를 읽는다.

CLI

#24469: Sui CLI가 이제 clap-complete를 통한 auto-complete를 지원한다.

sui completion --generate bash
sui completion --generate elvish
sui completion --generate fish
sui completion --generate powershell
sui completion --generate zsh

출력을 사용하는 shell의 올바른 디렉터리의 파일에 넣고, 예를 들어 fish의 경우 ~/.config/fish/completions/sui.fish에 넣은 뒤 shell을 다시 시작한다.

double TAB을 사용해 auto completion menu를 트리거한다.

#25226: sui move test가 이제 Sui의 gas meter와 limit를 사용한다.

#25405: primitive 인자가 reference 또는 mutable reference로 접근될 때 CLI가 Move call에 대한 그 인자의 type을 추론하지 못하던 문제를 수정한다.

#25082: 이제 sui move build --dump-bytecode-as-base64 --pubfile-path <file>를 사용해 dumped bytecode에 ephemeral address를 사용할 수 있다.

--dump 플래그는 --dump-bytecode-as-base64의 shorthand로 사용할 수 있다.

-e의 전체 플래그는 --build-env로 바뀌었으며, shorthand -e는 그대로 유지된다.

--pubfile-path-p와 함께 사용할 때의 bug도 수정했다.

#25592: sui client ptb 출력의 pretty printing을 다시 활성화하는 bug를 수정한다.

Indexing Framework

#25324: framework에서 error를 즉시 보이게 하기 위해 object_store crate 내부 retry를 비활성화한다.

#25325: ingestion stream의 memory leak를 수정한다.

#25334: concurrent pipeline에 ingestion backpressure를 활성화한다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.66.2

v1.65.2

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 111

#25366: 111은 execution mode와 transaction data 전반에서 check를 더 일관되게 만든다.

#24957: version 109에서 mainnet용 custom nonzero pcrs parsing을 활성화한다.

gRPC

#25392: #24797에서 도입된 bug를 수정하며, 이 bug는 fullnode가 1.64 release로 index를 복원했을 때 balance index가 부정확해질 수 있었다.

GraphQL

#24963: Balance.totalBalance가 이제 owned coin과 accumulator object의 balance 합계를 반환하며, 개별 coin 또는 address balance는 각각 Balance.coinBalanceBalance.addressBalance를 통해 조회할 수 있고, 이전 동작이 필요하면 coin balance 전용으로 Balance.coinBalance field를 선택하면 된다.

#25108: GraphQL에서 partial error를 올바르게 지원하며, 유효하지 않은 field에는 error message가 표시되고 유효한 field는 정상적으로 계속 표시된다.

CLI

#25016: --serialize-unsigned-transaction과 함께 사용할 때 sui client publishsui client upgrade command에서 --sender 플래그가 이제 올바르게 존중되며, 이전에는 sender가 gas object에서 잘못 추론되어 --sender 플래그를 무시했다.

Indexing Framework

#24066: BCS 파일 대신 zstd 압축 proto 파일을 ingest한다.

#24991: remote_client::RemoteIngestionClientstore_client::StoreIngestionClient가 되며, checkpoint source로 object_store::ObjectStore의 모든 유효한 구현을 지원한다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.65.2

v1.64.2

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 109

#25147: fix(sui-http): 명시적인 rustls::CryptoProvider를 사용한다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.64.2

v1.64.1

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 109

#24802: TxContext 인자가 이제 어떤 위치에 나타나도 PTB layer에서 호출 가능하다.

#24835: entry function에 대한 signature check를 비활성화하며, Move compiler 변경은 이후 뒤따른다.

#24895: testnet에서 address alias 기능을 활성화한다.

#24879: poseidon_bn254가 모든 네트워크에서 활성화된다.

gRPC

#24794: balance_changes가 요청되었지만 transaction이 아직 index되지 않았을 때 error를 반환한다.

GraphQL

#24782: Relay의 @refetchable annotation을 지원하기 위해 GraphQL Global Identification Specification의 일부인 Query.node(id: ID!): Node를 schema에 도입한다.

#24781: Epoch.totalTransactions가 이제 null 대신 조회 중인 checkpoint 시점의 최신 epoch 값에 대한 값을 반환한다.

#24750: JSON blob으로 effects와 transaction을 반환할 수 있도록 TransactionEffectseffectsJson, TransactiontransactionJson을 추가한다.

#24865: GraphQL request에 이제 단일 "rich query" limit가 적용되며, 이 limit는 단일 request가 database에 대해 만들 수 있는 전용 request 수의 budget을 강제한다.

#24836: balance change를 JSON blob으로 반환할 수 있도록 TransactionEffectsbalanceChangeEffectJson을 추가한다.

#24876: TransactionInput union에 BalanceWithdraw type을 추가한다.

#24770: Display v2 expression을 사용해 MoveValue에서 sub-slice를 추출하는 MoveValue.extract를 도입한다.

#24771: MoveValue를 GraphQL Address로 강제 변환하고 다른 checkpoint에서 address를 볼 수 있도록 MoveValue.asAddressIAddressable.addressAt를 도입한다.

#24772: dynamic field 이름을 Display v2 literal로 제공하는 DynamicFieldName.literal을 추가한다.

#24774: Move value를 대상으로 단일 format string을 평가하는 MoveValue.format을 추가한다.

#24775: PTB input은 type을 추론할 수 있으면 MoveValue로 표현된다.

#24776: system state와 관련된 field를 Epoch에서 제거하고 대신 전체 system state를 Epoch.systemState: MoveValue로 노출하며, 마찬가지로 ValidatorSet의 대부분 field를 ValidatorSet.contents: MoveValue로, ValidatorValidator.contents: MoveValue로 대체한다.

#24779: Query.suinsName(name: ...)Query.address(name: ...)로 바꾸고, IAddressable.defaultSuinsNameIAddressable.defaultNameRecord.target으로 바꾸며, 주어진 SuiNS 이름에 대한 SuiNS NameRecord를 가져오는 Query.nameRecord를 추가한다.

#25025: Balance.totalBalance가 이제 owned coin과 accumulator object의 balance 합계를 반환하며, 개별 coin 또는 address balance는 각각 Balance.coinBalanceBalance.addressBalance를 통해 조회할 수 있고, 이전 동작이 필요하면 coin balance 전용으로 Balance.coinBalance field를 선택하면 된다.

CLI

#24822: sui client publish | upgrade에서 다양한 플래그(예: dry-run)를 사용할 때의 문제를 수정한다.

#24844: --dump-bytecode-as-base64와 함께만 사용할 수 있는 --no-tree-shaking 플래그를 추가하며, 이를 통해 source code에서 사용 여부와 관계없이 모든 dependency를 json 출력의 dependency 목록에 유지하도록 보장하고, 기본적으로는 --no-tree-shaking이 false일 때 CLI가 publication/upgrade 시 사용되지 않는 dependency를 dependency 목록에서 제거한다.

Indexing Framework

#24925: watermark update interval에 optional jitter를 추가한다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.64.1

v1.63.4

Mainnet | Source: GitHub Release

📕 Note:

이 release에는 성능 수정이 포함되어 있으며 protocol version bump는 필요하지 않다.

Sui Protocol Version in this release: 107

#24974: write sync를 활성화하는 environment variable을 복원한다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.63.4

v1.63.3

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 107

#24856: [consensus] direct finalization을 개선한다. #24943: validator가 reject되어야 하는 transaction에 대해 합의하지 못하던 consensus issue를 수정한다.

노드(검증자 및 풀 노드)

#24742: transaction 서명과 집계된 validator 서명으로 transaction 제출을 처리하는 validator RPC handler를 비활성화한다.

Quorum Driver 또는 유사한 로직을 사용한 transaction 제출은 이제 더 이상 동작하지 않는다.

Transaction Driver와 관련 validator RPC handler만이 이제 Sui에 transaction을 제출하는 유일한 방법이다.

gRPC

#24820: balance_changes가 요청되었지만 transaction이 아직 index되지 않았을 때 error를 반환한다.

GraphQL

#24595: GraphQL에서 partial error를 올바르게 지원하며, 유효하지 않은 field에는 error message가 표시되고 유효한 field는 정상적으로 계속 표시된다.

#24679: query.simulateTransactionchecks_enableddo_gas_selection 인자를 지원한다.

#24681: GraphQL에서 partial error를 올바르게 지원하며, 유효하지 않은 field에는 error message가 표시되고 유효한 field는 정상적으로 계속 표시된다.

#24911: TransactionEffectseffectsJson, balanceChangesJson을, TransactiontransactionJson을 추가해 effects와 transaction을 JSON blob으로 반환할 수 있게 한다.

CLI

#24508: --verify-compatibility를 제거하고 --skip-verify-compatibility를 추가하며, 기본 동작은 로컬에서 upgrade compatibility error를 검사하는 것이다.

#24896: 새 package management system에 여러 변경 사항을 적용한다:

  • --no-tree-shaking 플래그는 오프라인 dump-bytecode-as-base64를 허용한다
  • move-analyzer bug를 수정한다
  • test-publish command를 개선해 Pub.localnet.toml 파일을 dependency 간에 더 쉽게 공유할 수 있게 한다
  • test-upgrade command를 추가한다
  • package와 그 dependency를 push-button 방식으로 로컬 배포할 수 있는 test-publish --publish-unpublished-deps command를 추가한다
  • error message를 수정한다

Indexing Framework

#24503: indexer, ingestion service, metrics service는 이제 실행 시 JoinHandle<()> 대신 Service를 반환하며, Service::main을 사용해 service가 정상 종료되거나 error와 함께 종료될 때까지 기다리거나 graceful shutdown으로 termination signal에 응답할 수 있고, Service는 shutdown process의 여러 측면을 custom할 수 있도록 wait_for_shutdown, join, shutdown function도 노출한다.

#24523: indexer가 --first-checkpoint로 초기화되었을 때 concurrent pipeline에 대한 pruning을 수정한다.



Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.63.3

v1.62.1

Mainnet | Source: GitHub Release

Click to open
Sui v1.62 Gas Schedule 업데이트(및 예상 사항)

Sui v1.62에는 실제 execution cost를 더 정확하게 반영하고 과도 청구를 줄이기 위한 몇 가지 새로운 gas 변경을 도입하는, 목표 지향적인 gas schedule 및 metering 수정이 포함되어 있다.

가스 일정 변경 요약

Dynamic field changes (largest behavioral impact)

Dynamic field operation은 이제 cache 상태에 따라 다른 비용을 청구한다:

  • dynamic field의 첫 번째 load(즉 runtime cache에 없고 transaction에서 생성되지 않은 경우)는 더 비싸다
  • transaction 내에서 같은 dynamic field를 이후에 load하는 경우상당히 더 저렴하다
  • 같은 transaction에서 앞서 생성한 dynamic field에 접근하는 경우상당히 더 저렴하다

Additional execution-level adjustments

다음 execution level 조정이 도입된다:

  • MoveLoc 비용 감소: 이전에는 값이 생성되지 않는데도 값 크기에 비례해 잘못 청구했지만, 이제는 상수 비용을 청구한다
  • ReadRef 비용 소폭 증가: 이 연산은 value copy를 생성하므로 이제 그 비용을 반영한다
  • Execution stack tracking: 더 정확한 stack-height metering으로 일부 instruction의 과도 청구를 줄인다
  • Primitive size accounting tuning: 여러 primitive type에 대해 계산된 "size"가 실제 크기와 더 잘 맞도록 조정되며, 여기에는 일부 감소와 증가가 포함된다

트랜잭션 샘플링에서 관찰된 영향

gas 변경을 검토하면서 수백만 건의 transaction을 backtest했다.

수백만 개의 샘플 transaction 전반에서:

  • **5.7%**에서 gas 사용량 변화가 있었고, 그중:
    • **1.3%**는 gas가 증가했다
    • **4.4%**는 gas가 감소했다
  • 모든 transaction 전체에서 gas cost 변화의 평균은 **−6.03%**였다
  • gas cost 변화의 중앙값은 **−21.52%**였다

영향을 받은 transaction의 분포를 보면:

  • 대략 75번째 percentile까지는 gas cost 변화가 순감소이다
  • 76번째 percentile 이후부터는 변화가 증가 쪽으로 이동한다
  • 극단값(0th/100th percentile)은 더 큰 변동을 보이며, 이는 대부분 dynamic-field 동작과 size/caching의 상호작용으로 설명된다

개발자에게 의미하는 것

대부분의 workload에서는 변화가 없음을 체감할 것이며, 수백만 건의 transaction 중 영향을 받은 비율은 5.7%에 불과하다.

변화가 있다면 비용 감소일 가능성이 더 높다.

비용이 큰 패턴

다음 중 일부 또는 전부를 수행하는 경우 transaction 비용이 더 비싸질 수 있다:

  • 고유한 dynamic field를 많이 읽는 경우
  • 읽는 field의 크기가 큰 경우
  • 각 field를 transaction당 몇 번만 읽는 경우

이는 cache되지 않은 dynamic field를 처음 load하는 비용이 이제 더 비싸기 때문이다.

더 저렴한 트랜잭션

다음 중 하나라도 해당하면 transaction 비용이 더 저렴해져야 한다:

  • 같은 transaction 안에서 작은 집합의 dynamic field를 반복해서 읽는 경우
  • dynamic field를 생성한 뒤 같은 transaction 안에서 다시 접근하는 경우

이제 이 경우는 cache를 인식하는 할인과 "transaction 내 생성" 할인 혜택을 받는다.

2차 효과

대부분의 다른 instruction 및 stack-metering 변경은 규모가 크지 않으며, compilation 최적화로 가는 길을 닦아준다.

시간이 지나면 가능한 한 copy보다 local move를 선호하도록 compiler가 작업하면, compiler는 이 변경에서 도입된 MoveLoc 비용 감소의 이점을 활용할 수 있게 될 것이다.

Click to open
PTB의 Non-public entry Function 변경

다음 release(v1.62)에는 non-public(private 또는 public(package)) entry function의 argument에 대한 새로운 검증 규칙 집합이 도입된다.

이 규칙은 기존 규칙을 완전히 대체하며, 대부분의 경우 더 많은 표현력을 허용한다.

이는 이전보다 entry function으로 더 많은 작업을 할 수 있음을 뜻한다.

대부분의 사람이 entry function 주변의 기존 규칙을 이해하지 못한다는 피드백을 받았지만, 이 게시물에서는 해당 규칙이 사라지므로 설명하지 않는다.

대신 앞으로 적용될 새 entry function 규칙에 초점을 맞춘다.

개요

간단히 말해 non-public entry function의 argument는 hot potato와 얽힐 수 없다.

예를 들어 다음 code를 보자.

module ex::m;

public struct HotPotato()

public fun hot<T>(x: &mut Coin<T>): HotPotato { ... }
entry fun spend<T>(x: &mut Coin<T>) { ... }
public fun cool(h: HotPotato) { ... }

다음 PTB 예시에서는 spend의 input coin이 spend function과 함께 사용될 때 entangled hot potato를 가지므로 유효하지 않다.

// Invalid PTB
0: ex::m::hot(Input(0));
1: ex::m::spend(Input(0)); // INVALID, Input(0) still hot via Result(0)
2: ex::m::cool(Result(0));

하지만 spend가 호출되기 전에 hot potato가 파괴되면 유효하다.

// Valid PTB
0: ex::m::hot(Input(0));
1: ex::m::cool(Result(0));
2: ex::m::spend(Input(0)); // Valid! Input(0) is not hot

아래에서는 이 규칙이 왜 존재하는지와 규칙이 어떻게 정의되는지 더 깊이 살펴본다.

새 규칙

동기

값을 entry function과 함께 사용할 때 왜 어떤 규칙이 필요한지 궁금할 수 있다.

원래 동기는 package 개발자가 entry function argument에 대해 일정한 의미의 "atomicity"를 보장할 방법을 갖게 하려는 것이었다.

즉 특정 entry function이 PTB 안의 유일한 command일 때 argument가 동일하게 동작하도록 보장하는 방법이다.

대표적인 예는 flash loan으로, 개발자는 특정 Coin이 flash loan에서 온 것이 아니고 겉보기에는 transaction sender가 "소유"한 것임을 보장하고 싶어 할 수 있다.

Move에서 flash loan과 유사한 패턴은 동작을 강제하기 위해 “hot potato” 패턴을 사용한다.

예를 들면 다음과 같다.

module flash::loan;

use sui::balance::Balance;
use sui::sui::SUI;

public struct Bank has key {
id: UID,
holdings: Balance<SUI>,
}

// This is a hot potato because it does not have `store` and does not have `drop`
public struct Loan {
amount: u64,
}

public fun issue(bank: &mut Bank, amount: u64): (Balance<SUI>, Loan) {
assert!(bank.holdings.value() >= amount);
let loaned = bank.holdings.split(amount);
(loaned, Loan { amount })
}

public fun repay(bank: &mut Bank, loan: Loan, repayment: Balance<SUI>) {
let Loan { amount } = loan;
assert!(repayment.value() == amount);
bank.holdings.join(repayment);
}

이 예시에서 issue가 호출되면 Loan hot potato가 생성된다.

PTB에서 issue가 호출되면, 생성된 Loan hot potato가 repay 호출로 파괴되지 않는 한 transaction은 성공하지 않는다.

non-public entry function에 대한 우리의 목표는 어떤 argument도 이 flash loan, 또는 유사한 hot potato 시나리오에 관여하지 않도록 보장하는 것이다.

다시 말해 non-public entry function의 argument는 entry function 호출 이후 PTB에서 동작을 강제하는 방식으로 얽힐 수 없다.

이를 위해 활성 상태인 hot potato value 수와 그것들이 어떤 value에 영향을 줄 수 있는지를 세는 algorithm으로 추적한다.

용어

규칙과 이를 정의하는 algorithm을 보기 전에 몇 가지 용어를 먼저 정리한다.

  • 규칙은 PTB에 정적으로 적용되며, 이는 PTB 실행이 시작되기 전에 검증이 이루어진다는 뜻이다
  • 일부 경우, 특히 shared object 주변에서는 규칙이 PTB 실행 중 동적으로 적용될 때보다 더 일반적이고 비관적으로 보일 수 있다
  • _value_는 모든 PTB Argument이며, 여기에는 Input, Result, NestedResult, 그리고 이미 smashed된 GasCoin이 포함된다
  • _result_는 PTB command가 반환한 value이며, ResultNestedResult로 참조된다
  • PTB command의 argument에는 by-reference(& 또는 &mut)와 by-value(복사 또는 move) 두 usage type이 있다
  • value의 type에 storedrop이 모두 없으면 그 value는 _hot_으로 간주된다
  • 이는 hot value의 type이 다음 case 중 하나일 수 있음을 의미한다
    • ability가 없음
    • copy
    • key
    • value는 sui::object::UIDcopy가 없으므로 keycopy를 동시에 가질 수는 없다는 점에 유의한다
  • 각 value는 하나의 _clique_에 속하며, clique는 함께 argument로 사용된 value와 그 result를 나타낸다
  • 각 clique에는 hot value의 개수를 나타내는 count가 있으며, 이는 result가 hot이면 증가하고, hot value가 moved될 때, 즉 by-value로 가져가 복사되지 않을 때 감소한다
    • 여기서 count는 미해결 hot potato, 또는 유사한 value가 몇 개인지 추적하고, clique는 그것들이 어떤 value를 제한하거나 영향을 줄 수 있는지 추적한다

알고리즘

  • PTB의 각 input은 count가 0인 자신의 clique에서 시작한다
  • value가 하나의 command에서 함께 사용되면(by reference 또는 by-value) 각 clique의 count를 더해 clique를 병합한다
  • argument의 병합된 clique count는 moved된 hot value마다 감소한다
  • command가 non-public entry function에 대한 Move call이면, 이 시점에서 argument의 병합된 clique count는 0이어야 한다
    • 이는 non-public entry function이 hot value를 받을 수는 있지만, 그것이 그 clique의 마지막 hot value여야 함을 의미한다
  • 각 command의 result는 argument의 병합된 clique에 포함된다
  • clique의 count는 hot result value마다 증가한다
  • NOTE: shared object가 by-value로 전달되는 경우에는 result value accounting 중 argument의 병합된 clique count를 infinity로 설정하는 특별 규칙이 있다
    • 자세한 내용은 아래 “Limitations” 섹션을 참고한다

예시

overview의 예시를 algorithm으로 좀 더 신중하게 따라가 보자.

이 예시에서는 각 command 사이에서 각 clique와 그 count를 보여 주며 algorithm을 따라간다.

// Invalid PTB
// Input 0: Coin<SUI>
// cliques: { Input(0) } => 0
0: ex::m::hot(Input(0));
// cliques: { Input(0), Result(0) } = 1
1: ex::m::spend(Input(0)); // INVALID, Input(0)'s clique has a count > 0
2: ex::m::cool(Result(0));

// Valid PTB
// Input 0: Coin<SUI>
// cliques: { Input(0) } => 0
0: ex::m::hot(Input(0));
// cliques: { Input(0), Result(0) } = 1
1: ex::m::cool(Result(0));
// cliques: { Input(0) } => 0
2: ex::m::spend(Input(0)); // Valid! Input(0)'s clique has a count of 0

위의 flash::loan module을 사용하면 더 복잡한 예시를 만들 수 있다.

// Invalid PTB
// Input 0: flash::loan::Bank
// Input 1: u64
// cliques: { Input(0) } => 0, { Input(1) } => 0,
0: flash::loan::issue(Input(0), Input(1))
// cliques: { Input(0), NestedResult(0,0), NestedResult(0,1) } => 1,
1: sui::coin::from_balance(NestedResult(0,0));
// cliques: { Input(0), NestedResult(0,1), Result(1) } => 1,
2: ex::m::spend(Result(1)); // INVALID, Result(1)'s clique has count > 0
3: sui::coin::into_balance(Result(1));
4: flash::loan::repay(Result(3), NestedResult(0,1));

command 1에서 생성된 Coin이 command 0의 flash loan에 직접 관여하지 않았더라도, 이는 hot value NestedResult(0,1)와 같은 clique에 속한다.

따라서 이 값은 private entry function ex::m::spend에 사용할 수 없다.

ex::m::spend가 호출되기 전에 flash::loan::repay로 loan을 상환했다면, 이는 허용된다.

이는 앞선 예시에서 본 경우와 같다.

제한 사항

위에서 언급했듯이 shared object를 by-value로 가진 clique는 항상 hot하다.

다시 말해 non-public entry function은 shared object를 by-value로 받을 수는 있지만, 이전에 shared object와 by-value로 상호작용한 clique의 value는 받을 수 없다.

왜 그럴까.

이 규칙은 shared object를 wrap할 수 없기 때문에 필요하며, shared object는 다시 shared되거나 삭제되어야만 한다.

이는 shared object가 hot potato와 유사한 방식으로 동작을 강제하는 데 사용될 수 있음을 뜻한다.

하지만 hot potato와 달리, function signature만 보고는 그것이 올바르게 사용되는지 알 수 없다.

이 algorithm이 "static"이 아니라 "dynamic"이었다면 더 명확성을 희생하는 대신 더 정확할 수 있었다.

즉 정적인 규칙 집합은 보통 동적인 규칙 집합보다 설명하고 따르기가 더 쉽다.

하지만 party objects는 shared object보다 더 좁은 경우에만 이 제한을 받게 될 것이다.

따라서 우리는 정적 시스템의 명확성을 희생하지 않고도 장기적으로 이 제한이 수용 가능하다고 본다.

출시 예정(v1.63 이상)

이후 버전에서는 entry function에 대한 signature 제한을 제거할 예정이다.

이는 모든 Move function이 entry가 될 수 있음을 뜻한다.

Sui Protocol Version in this release: 104

#24239: 104 - 103에서 Coin의 업데이트 이후 CoinMetadata post update를 갱신한다.

노드(검증자 및 풀 노드)

#24420: transaction 제출에 Quorum Driver를 사용하는 기능을 비활성화하며, TRANSACTION_DRIVER environment variable 설정은 이제 no-op이다.

JSON-RPC

#23737: 이 PR은 [#24192](#24192)와 함께 indexer가 ingestion 시작 지점을 결정하는 방식을 통합하고 watermark로 게이트된 backfill task를 도입한다.

  1. --skip-watermark는 제거되며, concurrent pipeline에 대한 watermark safety check를 우회하던 이전 기능은 더 이상 지원되지 않는다.
  2. --first-checkpoint는 더 이상 indexer가 구성된 checkpoint에서 ingestion을 시작하도록 강제하지 않는다. 이제 indexer는 항상 모든 pipeline에서 다음 checkpoint의 최소값을 시작 ingestion 지점으로 결정해 처리를 재개한다. 이번 release부터 --first-checkpoint는 아직 committer watermark가 없는 pipeline에만 적용되며, 이 pipeline은 구성된 값에서 처리를 재개하고, 기존 watermark가 있는 pipeline은 항상 자신의 다음 checkpoint에서 처리를 재개한다.
  3. 새 메커니즘인 watermark task는 운영자가 이력 backfill을 위해 여러 indexer instance에서 같은 pipeline을 실행할 수 있게 한다. 새 플래그 --task--reader-interval-ms가 이 메커니즘을 활성화한다. 이 플래그는 checkpoint가 대응하는 main pipeline의 reader_lo watermark보다 낮지 않은 한 checkpoint 데이터를 커밋하는 tasked indexer를 생성하며, indexer는 --reader-interval-ms에 따라 이 tasked pipeline이 main pipeline의 watermark를 얼마나 자주 poll할지 제어한다.

Migration guidance:

  1. --first-checkpoint를 새 pipeline의 초기 ingestion에만 사용한다면 추가 조치는 필요 없다.
  2. 이전에 --first-checkpoint와 선택적으로 --skip-watermark를 사용해 기존 table을 backfill했다면, --task, --reader-interval-ms, --first-checkpoint를 구성한 새 indexer instance를 시작해 동일한 workflow를 달성할 수 있다.
  3. --skip-watermark와 마찬가지로 --task는 sequential pipeline 실행에는 사용할 수 없다.

GraphQL

#24319: simulateTransaction call의 일부였던 transaction payload가 query payload의 일부로 잘못 분류되어 더 낮은 payload 크기 limit가 적용되던 bug를 수정한다.

#23928: SimulationResult에서 events field를 제거하며, 중복 제거를 위해 event는 이제 effects.events()를 통해서만 접근할 수 있다.

#23929: checkpoint에 포함되지 않으므로 simulated/executed transaction timestamp에 대해 null을 반환한다.

#24486: AvailableRange query에 전달된 type과 field를 검증한다.

CLI

#24367:

  • sui validator command가 transaction argument에 공유 TxProcessingArgs struct를 사용하도록 리팩터링해 sui client와의 일관성을 높였다
  • offline signing에 대해 더 명확한 지침을 제공하도록 serialize_unsigned_transaction help text를 갱신했다

Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.62.1

v1.61.2

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 103

#24343: coin.move에 framework 변경을 적용한다.

gRPC

#24244: 아직 완전히 저장되지 않은 새 checkpoint에 대해서는 "Internal Error" 대신 "Not Found"를 반환한다.

GraphQL

#24202: 어느 시점에 삭제되거나 wrap된 object의 object version을 pagination할 때 관련 bug를 수정한다.

#24325: simulateTransaction call의 일부였던 transaction payload가 query payload의 일부로 잘못 분류되어 더 낮은 payload 크기 limit가 적용되던 bug를 수정한다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.61.2

v1.60.1

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 101

#24073: Coin registry patch를 적용한다.

노드(검증자 및 풀 노드)

#24010: transaction 처리 기본값으로 Mysticeti 2.0과 TransactionDriver를 사용한다.

CLI

#24133: 로컬 네트워크에서 indexer 및/또는 GraphQL을 실행할 때 기존의 원격 postgress database와 통신할 수 있는 기능을 추가한다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.60.1

v1.59.1

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 100

#24108: private generics check를 단순화한다.

GraphQL

#23851: live object set query에 historical data가 포함되던 bug를 수정한다.

#23417: type, field, filter에 대해 데이터가 उपलब्ध한 checkpoint 범위를 질의하는 AvailableRange API를 추가한다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.59.1

v1.58.3

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 98

#23866: bytecode verifier의 문제를 수정한다.

JSON-RPC

#23766: get_transactions_by_move_function에서 결과 누락을 일으키던 잘못된 iter bound를 수정한다.

GraphQL

#23689: 위임된 operation ability의 address가 존재하는 경우 이를 표시하는 Validator.operationCap을 추가한다.

#23697: epoch 번호와 exchange rate의 매핑을 표시하는 Validator.exchangeRatesTable을 추가하며, 이 exchange rate는 과거 SUI staker 각각이 미래에 인출할 수 있는 SUI token 양을 결정하는 데 사용된다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.58.3

v1.57.3

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 97

#23858: bytecode verifier의 문제를 수정하는 새 protocol version을 추가한다.

JSON-RPC

#23766: get_transactions_by_move_function에서 결과 누락을 일으키던 잘못된 iter bound를 수정한다.

GraphQL

#23689: 위임된 operation ability의 address가 존재하는 경우 이를 표시하는 Validator.operationCap을 추가한다.

#23697: epoch 번호와 exchange rate의 매핑을 표시하는 Validator.exchangeRatesTable을 추가하며, 이 exchange rate는 과거 SUI staker 각각이 미래에 인출할 수 있는 SUI token 양을 결정하는 데 사용된다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.57.3

v1.57.2

Mainnet | Source: GitHub Release

Sui Protocol Version in this release: 96

#23650: mainnet에서 Mysticeti v2(Mysticeti fastpath) 지원을 활성화한다.

노드(검증자 및 풀 노드)

#23492: summary에 CheckpointArtifacts digest를 추가하며, 현재는 테스트를 위해 Devnet에서 활성화되어 있다.

gRPC

#22874: 새 CoinRegistry system object와 GetCoinInfo를 통합한다.

JSON-RPC

#22903: coin metadata 및 total supply API를 CoinRegistry system object와 통합한다.

GraphQL

#23597: GraphQL의 Query.coinMetadata API에 Coin Registry 지원을 추가한다.

#23636: nullable parameter를 채우기 위해 variable을 사용한 뒤 그 variable을 제공하지 않았을 때, 즉 유효한 경우에도 query가 실패하던 bug를 수정한다.

CLI

#23433: CLI 바이너리 protocol version이 네트워크와 같거나 더 새롭지 않을 때 upgrade command가 조기에 종료되던 bug를 수정한다.

#23533: transaction replay가 이제 Sui CLI의 자체 command인 sui replay를 가진다.


Full Log: https://github.com/MystenLabs/sui/commits/mainnet-v1.57.2


정보

이 페이지는 크기 제한을 유지하기 위해 일부만 표시한다. 전체 릴리스 기록은 GitHub Releases에서 확인한다.