refactor: frame/ のリファクタリングと、使い方解説ドキュメント#641
Conversation
… runtime behaivior
… weired runtime behaivior
… weired runtime behaivior (and explicitly impl it)
…to avoid weired runtime behaivior (and explicitly impl it)
… runtime behaivior (and explicitly impl it)
frame/enclave/src/enclave_use_case/state_runtime_enclave_use_case.rs
Outdated
Show resolved
Hide resolved
| Ok(()) | ||
| } | ||
|
|
||
| fn run<C>(self, enclave_context: &C, max_mem_size: usize) -> anyhow::Result<Self::EO> |
There was a problem hiding this comment.
max_mem_size はアプリ側で決める必要ありなケースがある模様
max_cipher_text_size とかいい名前はありそうだが?
モチベーションは、block chainへのtxから、何のデータが送られたか推測されないように、全てのサイズを整えるpaddingくん
There was a problem hiding this comment.
There was a problem hiding this comment.
そうですね! EnclaveからBCに向けてデータ吐き出す操作の時しか使われないはずなので :yosage: です!
There was a problem hiding this comment.
CommandByEnclaveKeySender の HostInput である input::Command のフィールドとして max_mem_size: usize をもたせる
をやる上で、環境変数にしました。
example層からnode層を経由してmodule層に渡す方法にちょっと悩み、request parameterで渡すよりも(クライアントサイドの後方互換性ぶっ壊したりとか考えると)環境変数のほうが良いよなと判断しまして。
環境変数だとそれはそれで便利な認識です。
There was a problem hiding this comment.
環境変数だとRemote Attestationで検証されるEnclaveコードハッシュ(MRENCLAVE)を変えずにAnonify運営者が型が許す任意の値をCMD_CIPHER_PADDING_SIZE に入れられてしまうことにより、クライアントごとのアプリケーション依存の命令Aと命令Bを識別しうるサーフェスが増えてしまう、と感じています。(原則、Enclaveコードの挙動はRemote Attestationで検証される用に実装すべき)
ですが、現状そこまでの脅威モデルは必要としていない&クライアント側の暗号化paddingなど未対応ということで、一旦このままでも良いかと思いますー。
There was a problem hiding this comment.
うわああ勉強になります...
環境変数にした部分はそこまで手間取ってもなかったので、修正できるならしちゃいたいなという気持ちです。
このPRの前の状況みたいに、register_*! マクロ引数にサイズを書く形なら、example層から一気にmodule層にサイズを渡すことができます。
一方で、本来サイズを使わないで良い構造にまでサイズが行き渡るのが違和感あり、できれば避けたいです。
サイズの良い渡し方、思いつくでしょうか...?
There was a problem hiding this comment.
今サイズの渡し方に悩んでいるのは、サイズを渡す口がHostInputにあるからな気がしてきました。
enclaveの挙動はenclaveコードの中でstaticに決まるべきという至言に基づくと、Host側でサイズが決められちゃうこの方針は最初から破綻してる。
寝入る前の脳トレとしてちょっと考えてみます!
There was a problem hiding this comment.
このあたりで定数値としてコンテキストにぶち込むのは一つの解決策。
上述の「本来サイズを使わないで良い構造にまでサイズが行き渡るのが違和感」な状況から構造的には何も変わってないが、コンテキストの使い方としては悪くもない気も。
ちゃんとやるなら、構造ごとに別個のコンテキストを取れるようにマクロを拡張するとよさそう。
There was a problem hiding this comment.
ということで色々と修正しました。
436fcff で環境変数にしちゃったやつをrevertし、
10e4812 でそれぞれの UseCase が異なるコンテキストを取れるようにマクロを修正し、
0a833d4 で、 UseCase の trait 側においては new で渡される enclave_context の型を何でもOKにし、
cee5884 で、 CommandByEnclaveKeySender, CommandByTreeKemSender においては AnonicyContext を一層ラップして cmd_cipher_padding_size も一緒に持った struct ContextWithCmdCipherPaddingSize をコンテキストとし受け取る
ようになりました。
最後の 73a16ee は名前合わせです。
example/erc20/enclave/src/ecalls.rs
Outdated
| ( | ||
| SEND_COMMAND_ENCLAVE_KEY_CMD, | ||
| CommandByEnclaveKeySender<NoAuth> | ||
| CommandByEnclaveKeySender<AnonifyEnclaveContext, Runtime<AnonifyEnclaveContext>,NoAuth> |
There was a problem hiding this comment.
これ、 AnonifyEnclaveContext が modules 以下だったら、 CommandByEnclaveKeySender の定義側で埋めることができる
…`. `host_input::Command` takes it.
…MEM_SIZE`. `host_input::Command` takes it." This reverts commit f9f0680.
… defined from example/**/enclave in order to be included in MRENCLAVE
| pub static ref ENCLAVE_CONTEXT_WITH_CMD_CIPHER_PADDING_SIZE: ContextWithCmdCipherPaddingSize<'static> = { | ||
| ContextWithCmdCipherPaddingSize { | ||
| ctx: &*ENCLAVE_CONTEXT, | ||
| cmd_cipher_padding_size: 100, |
There was a problem hiding this comment.
アプリケーション開発者がこの値をいじる必要があることを認識できるようにしたいですね。
(元々なってなかったですがmm)
docsに残すのがいいのかな
There was a problem hiding this comment.
一番良さそうだなって思うことを雑に書きます。
Enclaveの設定値は、ここの教え通り、ライブラリのバイナリにstaticに書き込まれているべきです。
こういうのは本来(今みたいに)ハードコードもすべきじゃないし、ましてやコード中で散逸すべきでもない。
ビルドパラメータであるのが一番ですね。
build.rs が build.toml (特に規格があるわけではないと思うけど) みたいなの読む形式になっているかのが一番キレイそうだなって思いました。
(Makefileでも良い)
There was a problem hiding this comment.
あざます!
staticに書き込まれるべきは完全同意です!
アプリケーション開発者がなんじゃそりゃとならないようにだけフォローできるといいなと思った次第です〜
Makefileも良さげですが、またmakeの変数増えてしまう心理的障壁との戦い。悩ましい
(一番よさそうなとこで大丈夫です)
There was a problem hiding this comment.
若干オフトピですが、Makefileは結構古代の技術だし苦しいですよね... $@ とかいい加減にしてほしい
できる限り build.rs で頑張れるといいなという思いがあるが、あんまりrustで巨大プロジェクトのビルドを頑張ったことないからMakefileをどこまで代替できるかは自信なしです。Makefileの依存グラフ記述力は馬鹿にできないですしね。
更にオフトピを重ねると、cargo-make っていうのはタスクランナーとして好んで使っています。依存関係記述力がどこまであるかはよくわからない 🙄
There was a problem hiding this comment.
cargo-makeめちゃ気になりますね
$@
$^
$<
$?
=
:=
?=
から脱却したい
There was a problem hiding this comment.
ここら辺とかはmakefileなくしているです
https://github.com/mobilecoinfoundation/mobilecoin/tree/master/sgx/build
| command_plaintext: CommandPlaintext<AP>, | ||
| enclave_context: &'c ContextWithCmdCipherPaddingSize<'c>, | ||
| user_id: Option<AccountId>, | ||
| _p: PhantomData<R>, |
There was a problem hiding this comment.
Phantomです 🙄
使うフィールドじゃないしくっそ適当でいいかなって...
There was a problem hiding this comment.
_rで固定観念に縛られてました
:kanzenrikai:
_p で 👍
|
レビューありがとうございましたマーーーーーーーーーーーーーーーーーーージします! |
Issueへのリンク
Fixes: #610
Fixes: #611
(e2e テストを走らせたく、ブランチ名を変えるために #638 を閉じて立て直しました)
やったこと
frame/以下のフレームワークはとても良いもの(特にecall_entry_point()を中心とした設計)だと思うが、実際に使ってみて慣れるまでに時間がかかったのと、名称や構造に一部違和感があったので、リファクタリングをする。またフレームワークの使い方ドキュメントがあると新feature実装や改修の際に役立つと感じたので追加する。
trait {Basic,StateRuntime}EnclaveUseCaseの関連関数にデフォルト実装がついていたのを外した。デフォルト実装に気づかず全部 impl したつもりになって、ランタイムでデバッグする必要に迫られるのを避けるため。やらないこと
誰か今後書いてくれたら嬉しいな
動作検証
CI pass (含む e2e)
テストのカバレッジを知らないので、これでどの程度自信を持ってよいのか...
特に、
cmd: u32の付け間違えなどに一抹の不安... → この箇所はセルフレビューでだいぶ自信持てた参考