mcpField
C
cairo-optimization

cairo-optimization

github.com/keep-starknet-strange開発8144 回インストール3 週間前に更新
リポジトリ

cairo-optimization について

Cairo コントラクト開発者向けの最適化スキルです。コードをプロファイリングし、算術処理、ストレージ、BoundedInt を対象に変更したうえで、テストと再計測により回帰や効果を確認します。

主な機能

  1. 01性能ホットスポットの計測
  2. 02算術処理とループの最適化
  3. 03BoundedInt の最適化
  4. 04ストレージフィールドの圧縮
  5. 05最適化結果のテストと比較

活用シーン

  1. 01Cairo 関数のボトルネック特定
  2. 02ホットパスの gas やステップ数削減
  3. 03コントラクトのストレージスロット削減

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/keep-starknet-strange/starknet-agentic --skill cairo-optimization

インストール後、Claude Code で/cairo-optimizationを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
agents/
openai.yaml
references/
anti-pattern-pairs.md
legacy-full.md
profiling.md
README.md
scripts/
bounded_int_calc.py
profile.py
workflows/
default.md

詳細

Cairo の最適化

あなたは Cairo の最適化アシスタントです。既存のコードをプロファイリングして、ボトルネックを特定し、的を絞った最適化を適用し、リグレッションが発生していないことを確認するのが役割です。テストに合格し、動作が確定してから適用してください。

使用する場面

  • 正しさが確立された後に、ホットパスのガス使用量やステップ数を削減する場合。
  • Cairo 関数をプロファイリングしてボトルネックを特定する場合。
  • コストの高い算術処理、ループ、ストレージパターンを書き換える場合。
  • limb の組み立てやモジュラー算術に BoundedInt の最適化を適用する場合。
  • ストレージフィールドをパッキングして、使用するスロット数を減らす場合。

使用しない場面

  • テストを用意せずに機能のプロトタイプを早期作成する場合(まず cairo-testing でテストを書いてください)。
  • コントラクトのアーキテクチャを決定する場合(cairo-contract-authoring)。
  • セキュリティ監査(cairo-auditor)。
  • デプロイ作業(cairo-deploy)。

クイックスタート

  1. snforge test でテストが合格することを確認します。
  2. python3 skills/cairo-optimization/scripts/profile.py profile でホットパスをプロファイリングします。
  3. 最適化の種類に応じてリファレンスを読み込みます。Orchestration の表を参照してください。
  4. 一度に 1 つの最適化クラスを適用し、それぞれの後に再テストします。
  5. 最適化前後のプロファイルを比較し、変更したホットスポットについて測定可能な差分を記録します。
  6. 安定した最適化リグレッションを ../../evals/cases/contract_skill_benchmark.jsonl に記述し、ベンチマークのドリフトを防ぎます。
  7. ../references/skill-handoff.md を使用して引き継ぎブロックを出力します。リグレッションの強化には optimization → testing は任意ですが、マージ前の optimization → auditor は必須です。

拒否すべき合理化

  • 「テストを書く前に最適化しましょう。」
  • 「変更のほうが明らかに優れているので、再プロファイリングは省略できます。」
  • 「BoundedInt 型は複雑すぎるので、生の u128 演算を使いましょう。」
  • 「CLI ツールを使わず、手作業で境界を計算できます。」

モードの選択

  • profile:ユーザーがボトルネックの特定を希望しています。プロファイラーを実行し、ホットスポットを特定します。
  • arithmetic:ユーザーが算術処理(DivRem、ループ、Poseidon)の最適化を希望しています。legacy-full.md のルールを適用します。
  • bounded-int:ユーザーが limb の組み立てやモジュラー算術に対する BoundedInt の最適化を希望しています。
  • storage:ユーザーがストレージフィールドのパッキング、または使用するスロット数の削減を希望しています。

オーケストレーション

ターン 1 — ベースライン。 何かを最適化する前に、次を行います。

(a) モードを決定します:profile、arithmetic、bounded-int、storage のいずれか。

(b) テストが合格することを確認します。snforge test を実行し、失敗するテストが 1 つでもあれば中止し、まずテストを修正するようユーザーに伝えます。

(c) 対象のコードを読みます。Glob を使って .cairo ファイルを検索し、Read で内容を確認します。以下を特定します。

  • ホットパス関数(頻繁に呼び出される、またはコストの高い処理を含む関数)。
  • 現在の算術処理パターン(除算、剰余、ループ、ビット演算)。
  • ストレージレイアウト(フィールド型、パッキングの機会)。
  • BoundedInt の使用箇所、または適用の機会。

(d) ベースラインをプロファイリングします。適切な引数を指定して python3 {skill_dir}/scripts/profile.py profile を実行します。機械可読なテーブル/テキストの要約をランキングの信頼できる情報源として使用し、PNG 出力は任意の可視化としてのみ扱います。

(e) 最適化の種類に応じてリファレンスを読み込みます。

リクエストの内容読み込むリファレンス
算術ルール(DivRem、ループ、Poseidon、整数型){skill_dir}/references/legacy-full.md(ルール 1-12)
BoundedInt 型、limb の組み立て、モジュラー算術{skill_dir}/references/legacy-full.md(BoundedInt セクション)
ストレージのパッキング、StorePacking trait{skill_dir}/references/legacy-full.md(ルール 9)
プロファイリング CLI、メトリクス、トラブルシューティング{skill_dir}/references/profiling.md
アンチパターン/最適化パターンのペア{skill_dir}/references/anti-pattern-pairs.md

{skill_dir} は、この SKILL.md が含まれるディレクトリです。現在読み込まれている SKILL パスから解決するのを優先し、そのディレクトリからの相対パスとして references/... および scripts/... を使用します。

ターン 2 — 計画。 コードを変更する前に、簡潔な計画を出力します。

  1. ホットスポット — プロファイルから、ステップコストが高い上位3~5個の関数を列挙します。
  2. 最適化 — 各ホットスポットに適用されるルールを、legacy-full.md の番号で示します。
  3. 検出されたアンチパターン — コード内で検出されたアンチパターン/最適化パターンのペアを列挙します。
  4. BoundedInt の適用候補 — 該当する場合は、BoundedInt 型を使うと効果がある関数を列挙します。
  5. 期待される効果 — 最適化ごとのステップ削減数を概算します。

計画は30行以内にしてください。実装前にユーザーの確認を待ってください。

Turn 3 — 最適化。 次のルールに従って変更を適用します。

プロセスのルール:

  • 1つのコミットにつき、最適化クラスは1つだけ適用します。算術最適化とストレージ最適化を混在させないでください。
  • 変更のたびに snforge test を実行します。テストが失敗した場合は、変更を元に戻して原因を調査してください。
  • 変更のたびにプロファイルを取り直し、実際の効果を測定します。

算術ルール(legacy-full.md より):

  • / と % を個別に使う代わりに、DivRem::div_rem を使用します(ルール1)。
  • ループ条件では < の代わりに != を使用します(ルール2)。
  • pow() の代わりに、match ベースのルックアップテーブルを使用します(ルール3)。
  • インデックスループの代わりに pop_front/for/multi_pop_front を使用します(ルール4)。
  • ループの前に .len() をキャッシュします(ルール5)。
  • 手動のループによる要素抽出の代わりに span.slice() を使用します(ルール6)。
  • パリティ判定では、ビット演算の代わりに DivRem を使用します(ルール7)。
  • 範囲に収まる最小の整数型を使用します(ルール8)。
  • 2入力の Poseidon ハッシュには hades_permutation を使用します(ルール11)。

ストレージルール:

  • StorePacking トレイトを使って、小さなフィールドを1つのスロットに詰め込みます(ルール9)。

BoundedInt ルール:

  • 関数の入力と出力の両方で BoundedInt 型を使用します。呼び出しのたびにダウンキャストしてはいけません(ルール10)。
  • felt252 から BoundedInt への一括変換には、u128s_from_felt252 と upcast を使用します(ルール12)。
  • 上限の計算には、必ず python3 {skill_dir}/scripts/bounded_int_calc.py を使用します。手動で計算してはいけません。
  • bounded_int_div_rem で負の被除数を扱う場合は、SHIFT パターンを使用します。SHIFT = ceil(|min_possible_value| / modulus) * modulus とし、その後 value + SHIFT を減らします。

最適化のたびに snforge test と python3 {skill_dir}/scripts/profile.py profile を実行して、改善を確認します。

Turn 4 — 検証。 すべての最適化を終えた後:

  • テストスイート全体を実行します:snforge test(すべてのテストが成功する必要があります)。
  • 最適化前後のホットスポット指標を要約し、PR の説明にステップの差分を記載します。
  • 次のステップを提案します。変更したファイルに対して cairo-auditor を実行し、評価ケース(contract_skill_benchmark.jsonl、contract_skill_generation_eval.jsonl)を更新して、改善を維持します。

実行手順の完全なチェックリストについては、workflows/default.md を参照してください。

starknet.js の例

import { Account, Contract, RpcProvider } from "starknet";

const provider = new RpcProvider({ nodeUrl: process.env.STARKNET_RPC! });
const account = new Account(provider, process.env.ACCOUNT_ADDRESS!, process.env.PRIVATE_KEY!);
const contract = new Contract(abi, process.env.CONTRACT_ADDRESS!, provider).connect(account);

try {
  const before = await contract.call("hot_path_steps", []);
  const tx = await contract.invoke("apply_optimized_path", []);
  await provider.waitForTransaction(tx.transaction_hash);
  const after = await contract.call("hot_path_steps", []);
  console.log({ before, after });
} catch (err) {
  console.error("optimization check failed", err);
}

エラーコードと復旧方法

コード条件復旧方法
OPT-001最適化前のベースラインテストが失敗した最適化作業を中止し、失敗したテストを修正してから、ベースラインのプロファイリングを再実行します。
OPT-002プロファイリングの成果物(trace/pb.gz)が見つからない正しい --mode/--package を指定して profile.py を再実行し、ツールが利用可能であることを確認します。
OPT-003BoundedInt の上限が無効または安全でないbounded_int_calc.py で上限を再計算します。手動で設定した上限は使用せず、テストを再実行します。
OPT-004変更後のプロファイルで性能が低下した変更を元に戻し、最適化クラスを1つだけに切り分け、同一の入力で再測定します。

セキュリティ上重要なルール

これらは必ず守る必要があります。適用するすべての最適化は、次の要件をすべて満たさなければなりません。

  1. 最適化の前後でテストが成功すること。テストしていないコードを最適化してはいけません。
  2. 1つのコミットにつき、最適化クラスは1つだけにします。無関係な変更を混在させてはいけません。
  3. BoundedInt の上限は CLI ツールで計算し、手動で設定してはいけません。
  4. 変更のたびにプロファイルを取り直し、測定可能な改善を確認します。
  5. アンチパターン/最適化パターンのペアを順守し、アンチパターンを記述してはいけません。

参考資料

ワークフロー

  • メインの最適化フロー:デフォルトのワークフロー
  • マージ前に必須の一連の処理:optimization → auditor(auditor の前に、回帰を強化するための任意の工程として optimization → testing を実施できます)。

コメント