Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file sc_rollup_proof_repr.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2022 Nomadic Labs <contact@nomadic-labs.com> *)(* Copyright (c) 2022 Trili Tech, <contact@trili.tech> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)typeerror+=Sc_rollup_proof_checkofstringtypeerror+=Sc_rollup_invalid_serialized_inbox_prooflet()=register_error_kind`Permanent~id:"Sc_rollup_proof_check"~title:"Invalid proof"~description:"An invalid proof has been submitted"~pp:(funfmtmsg->Format.fprintffmt"Invalid proof: %s"msg)Data_encoding.(obj1@@req"reason"string)(functionSc_rollup_proof_checkmsg->Somemsg|_->None)(funmsg->Sc_rollup_proof_checkmsg);register_error_kind`Permanent~id:"Sc_rollup_invalid_serialized_inbox_proof"~title:"Invalid serialized inbox proof"~description:"The serialized inbox proof can not be de-serialized"~pp:(funfmt()->Format.fprintffmt"Invalid serialized inbox proof")Data_encoding.unit(functionSc_rollup_invalid_serialized_inbox_proof->Some()|_->None)(fun()->Sc_rollup_invalid_serialized_inbox_proof)typereveal_proof=Raw_data_proofofstringletreveal_proof_encoding=letopenData_encodinginletcase_raw_data=case~title:"raw data proof"(Tag0)(obj2(req"reveal_proof_kind"(constant"raw_data_proof"))(req"raw_data"(check_sizeConstants_repr.sc_rollup_message_size_limitbytes)))(functionRaw_data_proofs->Some((),Bytes.of_strings))(fun((),s)->Raw_data_proof(Bytes.to_strings))inunion[case_raw_data]typeinput_proof=|Inbox_proofof{level:Raw_level_repr.t;message_counter:Z.t;proof:Sc_rollup_inbox_repr.serialized_proof;}|Reveal_proofofreveal_proofletinput_proof_encoding=letopenData_encodinginletcase_inbox_proof=case~title:"inbox proof"(Tag0)(obj4(req"input_proof_kind"(constant"inbox_proof"))(req"level"Raw_level_repr.encoding)(req"message_counter"Data_encoding.n)(req"serialized_proof"Sc_rollup_inbox_repr.serialized_proof_encoding))(function|Inbox_proof{level;message_counter;proof}->Some((),level,message_counter,proof)|_->None)(fun((),level,message_counter,proof)->Inbox_proof{level;message_counter;proof})inletcase_reveal_proof=case~title:"reveal proof"(Tag1)(obj2(req"input_proof_kind"(constant"reveal_proof"))(req"reveal_proof"reveal_proof_encoding))(functionReveal_proofs->Some((),s)|_->None)(fun((),s)->Reveal_proofs)inunion[case_inbox_proof;case_reveal_proof]typet={pvm_step:Sc_rollups.wrapped_proof;input_proof:input_proofoption}letencoding=letopenData_encodinginconv(fun{pvm_step;input_proof}->(pvm_step,input_proof))(fun(pvm_step,input_proof)->{pvm_step;input_proof})(obj2(req"pvm_step"Sc_rollups.wrapped_proof_encoding)(opt"input_proof"input_proof_encoding))letppppf_=Format.fprintfppf"Refutation game proof"letstartproof=let(moduleP)=Sc_rollups.wrapped_proof_moduleproof.pvm_stepinP.proof_start_stateP.proofletstopproof=let(moduleP)=Sc_rollups.wrapped_proof_moduleproof.pvm_stepinP.proof_stop_stateP.proof(* This takes an [input] and checks if it is at or above the given level.
It returns [None] if this is the case.
We use this to check that the PVM proof is obeying [commit_level]
correctly---if the message obtained from the inbox proof is at or
above [commit_level] the [input_given] in the PVM proof should be
[None]. *)letcut_at_levellevel(input:Sc_rollup_PVM_sig.input)=matchinputwith|Inbox_message{inbox_level=input_level;_}->ifRaw_level_repr.(level<=input_level)thenNoneelseSomeinput|Reveal_data->Someinputletproof_errorreason=letopenLwt_tzresult_syntaxinfail(Sc_rollup_proof_checkreason)letcheckpreason=letopenLwt_tzresult_syntaxinifpthenreturn()elseproof_errorreasonletcheck_inbox_proofsnapshotserialized_inbox_proof(level,counter)=matchSc_rollup_inbox_repr.of_serialized_proofserialized_inbox_proofwith|None->failSc_rollup_invalid_serialized_inbox_proof|Someinbox_proof->Sc_rollup_inbox_repr.verify_proof(level,counter)snapshotinbox_proofletvalidsnapshotcommit_level~pvm_nameproof=letopenLwt_tzresult_syntaxinlet(moduleP)=Sc_rollups.wrapped_proof_moduleproof.pvm_stepinlet*()=check(String.equalP.namepvm_name)"Incorrect PVM kind"inlet*input=matchproof.input_proofwith|None->return_none|Some(Inbox_proof{level;message_counter;proof})->let+inbox_message=check_inbox_proofsnapshotproof(level,Z.succmessage_counter)inOption.map(funi->Sc_rollup_PVM_sig.Inbox_messagei)inbox_message|Some(Reveal_proof(Raw_data_proofdata))->return_some(Sc_rollup_PVM_sig.Reveal(Raw_datadata))inletinput=Option.bindinput(cut_at_levelcommit_level)inlet*input_requested=P.verify_proofinputP.proofinlet*()=match(proof.input_proof,input_requested)with|None,No_input_required->return_unit|Some(Inbox_proof{level;message_counter;proof=_}),Initial->check(Raw_level_repr.(level=root)&&Z.(equalmessage_counterzero))"Inbox proof is not about the initial input request."|Some(Inbox_proof{level;message_counter;proof=_}),First_after(l,n)->check(Raw_level_repr.(level=l)&&Z.(equalmessage_countern))"Level and index of inbox proof are not equal to the one expected in \
input request."|(Some(Reveal_proof(Raw_data_proofdata)),Needs_reveal(Reveal_raw_dataexpected_hash))->letdata_hash=Sc_rollup_PVM_sig.Input_hash.hash_string[data]incheck(Sc_rollup_PVM_sig.Input_hash.equaldata_hashexpected_hash)"Invalid reveal"|None,(Initial|First_after_|Needs_reveal_)|Some_,No_input_required|Some(Inbox_proof_),Needs_reveal_|Some(Reveal_proof_),(Initial|First_after_)->proof_error"Inbox proof and input request are dissociated."inreturn(input,input_requested)moduletypePVM_with_context_and_state=sigincludeSc_rollups.PVM.Svalcontext:contextvalstate:statevalproof_encoding:proofData_encoding.tvalreveal:Sc_rollup_PVM_sig.Input_hash.t->stringoptionmoduleInbox_with_history:sigincludeSc_rollup_inbox_repr.Merkelized_operationswithtypeinbox_context=contextvalinbox:Sc_rollup_inbox_repr.history_proofvalhistory:Sc_rollup_inbox_repr.History.tendendletproducepvm_and_statecommit_level=letopenLwt_tzresult_syntaxinlet(moduleP:PVM_with_context_and_state)=pvm_and_stateinletopenPinlet*!(request:Sc_rollup_PVM_sig.input_request)=P.is_input_stateP.stateinlet*input_proof,input_given=matchrequestwith|No_input_required->return(None,None)|Initial->letlevel=Raw_level_repr.rootinletmessage_counter=Z.zeroinlet*inbox_proof,input=Inbox_with_history.(produce_proofcontexthistoryinbox(level,message_counter))inletinput=Option.map(funmsg->Sc_rollup_PVM_sig.Inbox_messagemsg)inputinletinbox_proof=Inbox_proof{level;message_counter;proof=Inbox_with_history.to_serialized_proofinbox_proof;}inreturn(Someinbox_proof,input)|First_after(level,message_counter)->let*inbox_proof,input=Inbox_with_history.(produce_proofcontexthistoryinbox(level,Z.succmessage_counter))inletinput=Option.map(funmsg->Sc_rollup_PVM_sig.Inbox_messagemsg)inputinletinbox_proof=Inbox_proof{level;message_counter;proof=Inbox_with_history.to_serialized_proofinbox_proof;}inreturn(Someinbox_proof,input)|Needs_reveal(Reveal_raw_datah)->(matchrevealhwith|None->proof_error"No reveal"|Somedata->return(Some(Reveal_proof(Raw_data_proofdata)),Some(Sc_rollup_PVM_sig.Reveal(Raw_datadata))))inletinput_given=Option.bindinput_given(cut_at_levelcommit_level)inlet*pvm_step_proof=P.produce_proofP.contextinput_givenP.stateinletmoduleP_with_proof=structincludePletproof=pvm_step_proofendinmatchSc_rollups.wrap_proof(moduleP_with_proof)with|Somepvm_step->return{pvm_step;input_proof}|None->proof_error"Could not wrap proof"