ton-bug-triage について
ton-bug-triage は、ローカルの TON tontester ネットワークでバグを再現・調査するスキルです。TON 開発者向けに、コントラクト起点とバリデーター動作のテスト手順、結果を解釈しやすくするスクリプトと証拠の記録方法をまとめています。
主な機能
- 01トランザクションまたはバリデーターテストの選択
- 02基本・混合バリデーターネットワークの起動
- 03Tolk のコンパイルと StateInit BoC の構築
- 04コントラクトのデプロイとメッセージ BoC の送信
- 05アカウント、トランザクション、実行ログの確認
活用シーン
- 01内部メッセージによるコントラクトバグの再現
- 02ベースラインと調査用バリデータービルドの比較
- 03クラッシュ、稼働状態、異常パケット処理の検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ton-blockchain/ ton-triage-skill --skill ton-bug-triageインストール後、Claude Code で/ton-bug-triageを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitignoreagents/openai.yamlreferences/bug_hunt_example.mdcontract_deploy_flow.mddiagnostic_checklist.mdliteclient_fallback.mdprobing_patterns.mdwallet_and_deploy_helpers.mdscripts/account_state.pyaddress_info.pybuild_stateinit.pycompile_tolk.pydemo_wallet_flow.pydump_boc.pyget_method.pyinspect_latest_transaction.pyrun_basic_network.pyrun_fift_script.pyrun_liteclient.pyrun_mixed_network.pysend_boc.pysummarize_run.pyton_triage_lib.pywallet_send.pyscripts/fift/build_stateinit.fifdump_boc.fifnew-wallet-save-stateinit.fif詳細
TON Bug Triage
ローカルの tontester ネットワークで何かを立証することが目的で、単にバリデーターを起動するだけではない場合に、このスキルを使用します。
典型的な用途:
- コントラクトをデプロイし、内部メッセージでバグを発生させる
- ベースラインのバリデータービルドと調査対象のバリデータービルドを比較する
- クラッシュ、ライブネスの失敗、不正パケットの処理経路、互換性に関する主張を検証する
- ローカル TON 再現用の、メンテナーに提出できる証拠を収集する
基本方針は、問いに答えられる最小のトポロジーを選び、実行前に成功条件を定め、結果を解釈するのに十分な証拠を集めることです。
作業モデル
以下のパスを区別してください。
- スキルスクリプト:
scripts/run_basic_network.pyなど、このスキルのディレクトリにあるファイル - ソースツリー:
--repo-rootで指定する、実際の TON チェックアウト - ビルドディレクトリ:
validator-engine、create-state、tonlibjson、tolkなどのバイナリとライブラリ - 作業ディレクトリ:実行ごとの状態、ログ、設定、出力されたアーティファクト
スキルのディレクトリとリポジトリが同じものだと想定しないでください。スクリプトはスキル内にあります。指定したリポジトリとビルドに対して動作します。
wallet-env.txt は、ランチャーから後続のヘルパーへの主要な引き継ぎ用アーティファクトです。
これらのヘルパーは tontester の内部実装とプライベート API に依存します。tontester が変更された場合は、ヘルパーの動作、生成されたバインディング、またはコマンドの前提を調整する必要があると想定してください。
ワークフローの選択
実行を始める前に、ワークフローを 1 つ選んでください。
-
Workflow A — transaction 経由の発生コントラクトのデプロイ、内部メッセージの送信、または不正/カスタムペイロードのコントラクトアカウントへの配信によってバグに到達する場合に使用します。 -
Workflow B — バリデーターの動作による発生パッチ適用済みのバリデーターコード、異なるビルドの混在、コンセンサスへの干渉、不正なプロトコルパケット、トラフィックの順序変更、または意図的に無効なブロック動作が必要な場合に使用します。
再現に両方が関係する場合は、まず次の点を確認してください。通常のデプロイ/送信経路の後、未変更のネットワークで発生させられますか? 可能であれば、Workflow A から始めてください。不可能であれば、Workflow B として扱ってください。
基本ルール
-
問いに答えられる最小のネットワークから始めます。 ピア、コンセンサス、または異なるビルドの混在が必要でない限り、バリデーターは 1 台にします。
-
zerostate の編集よりも、通常のデプロイ/送信フローを優先します。 zerostate の変更後にしか再現しない場合は、そのことを明確に伝えてください。
-
ベースラインと調査対象のビルドを分けます。 通常、ベースラインには
vanilla-build/を、変更したビルドにはbuild/またはbuild-probing/を使用します。 -
実行前に成功条件を決めます。 例:対象の
mc_seqno、明示的なクラッシュマーカー、プロセスの終了、アクティブなコントラクトアカウント、検査済みのトランザクション、または不正パケットに対する正常なノードの拒否などです。 -
Workflow B では、調査対象ノードが自身の挙動から免疫を持つようにします。 運用上の意味:調査対象ノードは不正または敵対的な挙動を送出しても、正常なノードで対象の影響が観測されるまで稼働し続けなければなりません。調査対象ノードが先に停止し、その停止が結果の説明となり得る場合、その実行は無効です。
-
同じシナリオを再実行するのに十分な証拠を記録します。 実行ディレクトリ、ビルドディレクトリ、コマンド、関連するアドレス、エクスポートしたアーティファクトを保存してください。
-
メンテナーに提出できる状態と判断する前に、クリーンなチェックアウトまたはデタッチされたワークツリーから、意図したアーティファクトだけを使って再実行してください。
コアスクリプト
単発のシェルコマンド列より、同梱スクリプトを優先してください。
-
scripts/run_basic_network.py1 つのビルドから 1 つ以上のバリデーターを起動します。--emit-wallet-env、--base-port、--validators、--keep-aliveをサポートしています。 -
scripts/run_mixed_network.py異なるビルドディレクトリからベースラインバリデーターとプロービングバリデーターを起動します。悪意のあるノードと正直なノードの実験、ログベースのクラッシュ検出、プロービングノードの生存確認に使用します。 -
scripts/compile_tolk.py.tolkソースを.fifにコンパイルし、コントラクトコードの BoC を生成します。tolkバイナリがリポジトリのHEADに対して古い場合は、必ず失敗します。 -
scripts/build_stateinit.pyコードと、オプションのデータおよびライブラリ辞書 BoC から、デプロイ可能なStateInitBoC を作成します。 -
scripts/run_fift_script.py正しいインクルードパスを指定して.fifスクリプトを実行します。 -
scripts/wallet_send.pyウォレット署名済みメッセージを作成し、必要に応じて送信します。デプロイには--init-bocを、任意の内部ペイロードには--body-bocを使用します。 -
scripts/send_boc.pywallet_send.pyで再構築せずに、事前に作成したシリアライズ済み外部メッセージ BoC を tonlib 経由で送信します。 -
scripts/address_info.pyヘルパーの入力を照合する必要がある場合に、raw 形式と friendly 形式の TON アドレスを正規化して調査します。 -
scripts/account_state.pyraw アカウント状態を取得し、調査用にコードとデータの BoC をダンプします。 -
scripts/get_method.pytonlib 経由で get-method を実行し、JSON を出力します。 -
scripts/inspect_latest_transaction.pyアカウントの最新トランザクションを取得し、raw トランザクションデータをエクスポートします。tonlib がメッセージ本体や初期状態をmsg.dataRawとして返した場合は、それらの BoC も保存します。 -
scripts/run_liteclient.pywallet-env.txt、または明示的に指定したリポジトリ、ビルド、設定の入力を使用してlite-clientコマンドを実行します。 -
scripts/dump_boc.pyFift を使用して BoC のセルツリーを出力します。ペイロード、StateInit、エクスポートしたトランザクションデータ、ダンプしたアカウントのコードやデータに使用します。 -
scripts/summarize_run.py完了済みまたは実行中の実行ディレクトリについて、ノードの稼働状況とクラッシュの兆候を要約します。 -
scripts/demo_wallet_flow.pyシンプルなウォレットのフローをエンドツーエンドで検証する、動作確認済みのスクリプトです。
ワークフロー A
トリガーが「コントラクトをデプロイしてから、メッセージを送信する」の場合は、ワークフロー A を使用します。
--emit-wallet-envを指定して、小規模なネットワークを起動します。scripts/compile_tolk.pyでコントラクトをコンパイルします。Tolk を使用しない場合は、Fift アセンブリーから手作業で作成したコード BoC を用意します。scripts/build_stateinit.pyでデプロイ可能なStateInitを構築します。 コントラクトで実際に必要な場合にのみ、--data-bocと--library-bocを指定します。- 資金がある組み込みの
main-walletから、scripts/wallet_send.py --init-bocを使ってデプロイします。--init-bocを使うデプロイメッセージは、コントラクトの内部メッセージハンドラーも呼び出すことがあります。別途トリガーを送信する前に、デプロイトランザクション自体によってコントラクトの状態が変化したか確認してください。 - アクティベーションを待ちます。
マスター チェーンが 1 回進むだけで十分だと決めつけず、
account_state.pyとコントラクト固有の get メソッドを使うことをおすすめします。 - ペイロードがカスタム形式またはバイナリーの場合は、トリガーボディを BoC として構築します。
run_fift_script.pyを使うと、単発のbody.bocを最も簡単に生成できます。 scripts/wallet_send.py --body-bocでトリガーを送信します。--body-bocは正式なペイロード指定方法であり、--commentを上書きします。 署名済みの外部メッセージ BoC がすでにある場合は、wallet_send.pyで再構築せず、代わりにscripts/send_boc.py --bocを使います。--wait-mc-advanceで確認できるのは、ネットワークが稼働していることです。トランザクションの成功、デプロイのアクティベーション、コントラクトの状態変化は確認できません。必ず対象アカウントを直接調べてください。inspect_latest_transaction.py --out-dirとdump_boc.pyを使って観察します。 エクスポートされたtransaction-data.bocとin-msg-body.bocが、セルレベルのデバッグの出発点になります。 tonlib ベースのヘルパーがクラッシュする場合(よくある症状:KeyError: '@extra')、すべての観察手順でフォールバックとしてrun_liteclient.pyを使ってください。references/liteclient_fallback.mdを参照してください。
一連の手順を最初から最後まで実行する例は、references/contract_deploy_flow.md を参照してください。
シンプルなウォレットのスモークテスト手順のみについては、references/wallet_and_deploy_helpers.md を参照してください。
ワークフロー B
トリガーが「バリデーターの動作を変更してから、正常なノードの反応を観察する」の場合は、ワークフロー B を使用します。
- 調査用の変更を加える前に、ベースラインのビルドをスナップショットします。
- 調査用のビルドのみをパッチし、動作の変更はすべて、明示的な
TON_PROBING_*環境変数で制御します。 - 混在トポロジーと、成功条件および失敗条件を明確に設定します。
--success-log、--failure-log、--require-node-alive、--require-node-deadは意図を持って使用します。 scripts/run_mixed_network.pyで混在ネットワークを実行します。- 主張の両方の側面を確認します。 調査用マーカーに到達したことと、正常なノードへの影響が発生した、または発生しなかったことを確認します。
scripts/summarize_run.pyで実行結果を要約し、要約で示された箇所に限って、個別のログを手動で調べます。
よくあるパッチのパターンについては、references/probing_patterns.md を参照してください。
最初から最後まで実行する例については、references/bug_hunt_example.md を参照してください。
否定的な結果
「再現しなかった」という結果も、有用な証拠です。次のすべてを満たす場合にのみ、実行結果を真の否定的な結果として扱ってください。
- 選択したワークフローで、トリガーパスが実際に実行された
- 関連する調査マーカーまたはトリガーマーカーが存在した
- バグが発生しなかったことに意味がある程度に、ネットワークが健全な状態を保った
- 観察手順で、適切なアカウント、トランザクション、またはノードログを確認した
- 対象の効果がないまま、タイムアウトまたは seqno の目標に到達した
問題のない再実行で同じ結果になり、残っている変更が軽微なパラメーター調整だけの場合は、試行を打ち切り、否定的な結果を報告してください。
反復とデバッグ
-
compile_tolk.pyが古いビルドに関するエラーで失敗した場合は、まずtolkを再ビルドします。 正確な修正コマンドは通常、ninja -C <build-dir> tolkです。 -
デプロイが成功したように見えても、デプロイ先が空のままの場合は、まず確認が早すぎなかったかを確認します。 デプロイ経路に問題があると決めつけず、アクティベーションを待ちます。
-
コントラクトがアクティブなのに、想定した get-method が失敗する場合は、ネットワークトポロジーを変更する前に、メソッド ID と初期データのレイアウトを確認します。
-
inspect_latest_transaction.pyに想定と異なるペイロードが表示された場合は、元のトリガー BoC とエクスポートされたin-msg-body.bocの両方をダンプし、セルツリーを比較します。 -
Workflow B でプロービングマーカーが見つからない場合は、環境変数がノードに渡されていないか、パッチを適用したコードパスが実行されていません。
-
対象の効果が確認される前にプロービングノードが停止した場合、その実行は無効です。
証拠の基準
主張を裏付けるのに十分な情報を記録します。
- 実行ディレクトリの正確なパス
- 使用したビルドディレクトリ
- 使用した成功条件
- 関連する起動コマンドとヘルパーコマンド
- 対象アドレスまたはノード名
- Workflow A のエクスポート済みトランザクションと BoC アーティファクト
- Workflow B のノード稼働状況とログマーカー
Workflow A では、--wait-mc-advance は稼働状況を示すヒントにすぎないことを忘れないでください。対象アカウントまたはトランザクションで成功を確認します。
トラブルシューティング
pythonが見つからない場合は、python3を使用します。tonapiバインディングが見つからない場合は、通常、ヘルパーがtest/tontester/generate_tl.pyからバインディングを生成します。- ヘルパーをリポジトリの外にコピーした場合も、実際のリポジトリを
--repo-rootとして渡し続けます。インクルードファイルと生成アーティファクトはスキルフォルダーではなく、リポジトリから取得されます。 - tonlib ベースのスクリプト(
account_state.py、get_method.py、inspect_latest_transaction.py、wallet_send.py --auto-seqno)がKeyError: '@extra'または類似の tonlib ラッパーエラーでクラッシュする場合は、ローカルの tonlib ビルドに互換性の問題があります。確認にはlite-clientを使用し、--auto-seqnoの代わりに手動の--seqnoを指定してwallet_send.pyを使用してください。 共通のフォールバック手順については、references/liteclient_fallback.mdを参照してください。 vanilla-build/CMakeCache.txtがbuild/を指している場合は、vanilla-buildを無効として扱い、再作成します。誤ったディレクトリに再設定されるビルドツリーを信頼しないでください。- 渡されたビルドディレクトリに
lite-clientがあると決めつけないでください。チェックアウトによっては、create-state、tonlibjson、tolkしかビルドされていない場合があります。 - ディスクの空き容量がない場合は、再試行する前に古い
run-*ディレクトリを削除します。
参考資料
-
references/wallet_and_deploy_helpers.md実証済みのシンプルなウォレットのスモークテスト手順については、こちらを参照してください。 -
references/contract_deploy_flow.mdWorkflow A の一般的なコンパイル、デプロイ、トリガー、確認の手順については、こちらを参照してください。 -
references/liteclient_fallback.mdtonlib ベースのヘルパーが失敗し、Workflow A でlite-clientによる確認または手動でのウォレット seqno 処理が必要な場合は、こちらを参照してください。 -
references/probing_patterns.mdWorkflow B のコード変更を設計する際は、こちらを参照してください。 -
references/diagnostic_checklist.md実行が完了しても結果が不明な場合は、こちらを参照してください。 -
references/bug_hunt_example.md複数ネットワークが関係する具体的な否定的結果の例については、こちらを参照してください。