123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* *)(* 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+=Parsing_errortypeerror+=Invalid_signaturelet()=register_error_kind`Permanent~id:"parsing_error"~title:"Parsing error"~description:"Raised when a block header has not been parsed correctly"~pp:(funppf()->Format.fprintfppf"Block header parsing error")Data_encoding.empty(functionParsing_error->Some()|_->None)(fun()->Parsing_error)let()=register_error_kind`Permanent~id:"invalid_signature"~title:"Invalid signature"~description:"Raised when the provided signature is invalid"~pp:(funppf()->Format.fprintfppf"Invalid signature")Data_encoding.empty(functionInvalid_signature->Some()|_->None)(fun()->Invalid_signature)typeoperation_data=unitletoperation_data_encoding=Data_encoding.unittypeoperation_receipt=unitletoperation_receipt_encoding=Data_encoding.unitletoperation_data_and_receipt_encoding=Data_encoding.conv(function((),())->())(fun()->((),()))Data_encoding.unittypeoperation={shell:Operation.shell_header;protocol_data:operation_data;}letacceptable_passes_op=[]letcompare_operations__=0letvalidation_passes=[]typeblock_header_data={command:Data.Command.t;signature:Signature.t;}typeblock_header={shell:Block_header.shell_header;protocol_data:block_header_data;}letblock_header_data_encoding=Data_encoding.conv(fun{command;signature}->(command,signature))(fun(command,signature)->{command;signature})Data.Command.signed_encodingtypeblock_header_metadata=unitletblock_header_metadata_encoding=Data_encoding.unitletmax_block_length=Data_encoding.Binary.lengthData.Command.encoding(Activate_testchain{protocol=Protocol_hash.zero;delay=0L})+Signature.sizeletmax_operation_data_length=0letcheck_signaturectxt~chain_id{shell;protocol_data={command;signature}}=letbytes=Data.Command.forgeshellcommandinData.Pubkey.get_pubkeyctxt>>=funpublic_key->fail_unless(Signature.check~watermark:(Block_headerchain_id)public_keysignaturebytes)Invalid_signaturetypevalidation_state=Updater.validation_resultletcurrent_context({context;_}:validation_state)=returncontext(* temporary hardcoded key to be removed... *)letprotocol_parameters_key=["protocol_parameters"]letprepare_applicationctxtcommandleveltimestampfitness=matchcommandwith|Data.Command.Activate{protocol=hash;fitness;protocol_parameters}->letmessage=Some(Format.asprintf"activate %a"Protocol_hash.pp_shorthash)inContext.setctxtprotocol_parameters_keyprotocol_parameters>>=functxt->Updater.activatectxthash>>=functxt->return{Updater.message;context=ctxt;fitness;max_operations_ttl=0;last_allowed_fork_level=level;}|Activate_testchain{protocol=hash;delay}->letmessage=Some(Format.asprintf"activate testchain %a"Protocol_hash.pp_shorthash)inletexpiration=Time.addtimestampdelayinUpdater.fork_test_chainctxt~protocol:hash~expiration>>=functxt->return{Updater.message;context=ctxt;fitness;max_operations_ttl=0;last_allowed_fork_level=Int32.succlevel;}letbegin_application~chain_id~predecessor_context:ctxt~predecessor_timestamp:_~predecessor_fitness:_block_header=Data.Init.check_initedctxt>>=?fun()->check_signaturectxt~chain_idblock_header>>=?fun()->prepare_applicationctxtblock_header.protocol_data.commandblock_header.shell.levelblock_header.shell.timestampblock_header.shell.fitnessletbegin_partial_application~chain_id~ancestor_context~predecessor_timestamp~predecessor_fitnessblock_header=begin_application~chain_id~predecessor_context:ancestor_context~predecessor_timestamp~predecessor_fitnessblock_headerletbegin_construction~chain_id:_~predecessor_context:ctxt~predecessor_timestamp:_~predecessor_level:level~predecessor_fitness:fitness~predecessor:_~timestamp?protocol_data()=matchprotocol_datawith|None->(* Dummy result. *)return{Updater.message=None;context=ctxt;fitness;max_operations_ttl=0;last_allowed_fork_level=0l;}|Some{command;_}->Data.Init.check_initedctxt>>=?fun()->prepare_applicationctxtcommandleveltimestampfitnessletapply_operation_vctxt_=Lwt.return(Error[])(* absurd *)letfinalize_blockstate=return(state,())letrpc_services=Services.rpc_services(* temporary hardcoded key to be removed... *)letsandbox_param_key=["sandbox_parameter"]letget_sandbox_paramctxt=Context.getctxtsandbox_param_key>>=function|None->return_none|Somebytes->matchData_encoding.Binary.of_bytesData_encoding.jsonbyteswith|None->failwith"Internal error: failed to parse the sandbox parameter."|Somejson->return_somejsonletinitctxtblock_header=Data.Init.tag_first_blockctxt>>=?functxt->get_sandbox_paramctxt>>=?funsandbox_param->beginmatchsandbox_paramwith|None->returnctxt|Somejson->Data.Pubkey.may_change_defaultctxtjson>>=functxt->returnctxtend>>=?functxt->return{Updater.message=None;context=ctxt;fitness=block_header.Block_header.fitness;max_operations_ttl=0;last_allowed_fork_level=block_header.level;}