123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* Copyright (c) 2019 Nomadic Labs, <contact@nomadic-labs.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. *)(* *)(*****************************************************************************)moduleBounded_encoding=structopenData_encodingmoduleM:sigtype'atvalcreate:'a->'at*('a->unit)valmap:'at->('a->'b)->'btvalmap2:'at->'bt->('a->'b->'c)->'ctvalencoding:'aData_encoding.tt->'aData_encoding.tend=structtype'at={get:unit->'a;mutableon_update:(unit->unit)list}typedeps=D:'at->depsletregister_on_updatef(Dx)=letold=x.on_updateinx.on_update<-f::oldletmake_with_depscachedepsf=letres={get=(fun()->match!cachewith|Somex->x|None->letr=f()incache:=Somer;r);on_update=[];}inletinvalidate()=cache:=None;List.iter(funf->f())res.on_updateinList.iter(register_on_updateinvalidate)deps;resletcreatex=letcache=ref(Somex)inletres=make_with_depscache[](fun()->(* The cache is always set to some value, this function will never be called *)assertfalse)inletsetx=cache:=Somex;List.iter(funf->f())res.on_updatein(res,set)letmapxf=make_with_deps(refNone)[Dx](fun()->f(x.get()))letmap2xyf=make_with_deps(refNone)[Dx;Dy](fun()->f(x.get())(y.get()))letgetx=x.get()letencodingx=delayed(fun()->getx)let%expect_test_=letx,set_x=create4inlety,_set_y=create4inletz=map2xy(funxy->print_endline"compute z";x+y)in[%expect{||}];print_int(getz);[%expect{|
compute z
8 |}];print_int(getz);[%expect{| 8 |}];set_x1;print_int(getx);[%expect{| 1 |}];print_int(getz);[%expect{|
compute z
5 |}]end(* FIXME: https://gitlab.com/tezos/tezos/-/issues/3370
all constants below are arbitrary high bounds until we have the
mechanism to update them properly. *)letblock_header_max_size,set_block_header_max_size=M.create(8*1024*1024)letblock_locator_max_length,set_block_locator_max_length=M.create1000letoperation_max_size,set_operation_max_size=M.create(Some(128*1024))letoperation_list_max_size,set_operation_list_max_size=M.create(Some(1024*1024))letoperation_list_max_length,set_operation_list_max_length=M.createNoneletoperation_max_pass,set_operation_max_pass=M.create(Some8)letprotocol_max_size,set_protocol_max_size=M.create(Some(2*1024*1024))letmempool_max_operations,set_mempool_max_operations=M.create(Some4000)letblock_header=M.mapblock_header_max_size(funmax_size->Block_header.bounded_encoding~max_size())|>M.encodingletblock_locator=M.map2block_header_max_sizeblock_locator_max_length(funmax_header_sizemax_length->Block_locator.bounded_encoding~max_header_size~max_length())|>M.encodingletoperation=M.mapoperation_max_size(funmax_size->Operation.bounded_encoding?max_size())|>M.encodingletmap4xyztf=M.map2(M.map2xy(funxy->(x,y)))(M.map2zt(funzt->(z,t)))(fun(x,y)(z,t)->fxyzt)letoperation_list=map4operation_list_max_lengthoperation_list_max_sizeoperation_max_sizeoperation_max_pass(funmax_lengthmax_sizemax_operation_sizemax_pass->Operation.bounded_list_encoding?max_length?max_size?max_operation_size?max_pass())|>M.encodingletprotocol=M.mapprotocol_max_size(funmax_size->Protocol.bounded_encoding?max_size())|>M.encodingletmempool=M.mapmempool_max_operations(funmax_operations->Mempool.bounded_encoding?max_operations())|>M.encodingendtypet=|Get_current_branchofChain_id.t|Current_branchofChain_id.t*Block_locator.t|DeactivateofChain_id.t|Get_current_headofChain_id.t|Current_headofChain_id.t*Block_header.t*Mempool.t|Get_block_headersofBlock_hash.tlist|Block_headerofBlock_header.t|Get_operationsofOperation_hash.tlist|OperationofOperation.t|Get_protocolsofProtocol_hash.tlist|ProtocolofProtocol.t|Get_operations_for_blocksof(Block_hash.t*int)list|Operations_for_blockofBlock_hash.t*int*Operation.tlist*Operation_list_list_hash.path|Get_checkpointofChain_id.t|CheckpointofChain_id.t*Block_header.t|Get_protocol_branchofChain_id.t*int(* proto_level: uint8 *)|Protocol_branchofChain_id.t*int(* proto_level: uint8 *)*Block_locator.t|Get_predecessor_headerofBlock_hash.t*int32|Predecessor_headerofBlock_hash.t*int32*Block_header.tletencoding=letopenData_encodinginletcase?max_length~tag~titleencodingunwrapwrap=P2p_params.Encoding{tag;title;encoding;wrap;unwrap;max_length}in[case~tag:0x10~title:"Get_current_branch"(obj1(req"get_current_branch"Chain_id.encoding))(functionGet_current_branchchain_id->Somechain_id|_->None)(funchain_id->Get_current_branchchain_id);case~tag:0x11~title:"Current_branch"(obj2(req"chain_id"Chain_id.encoding)(req"current_branch"Bounded_encoding.block_locator))(function|Current_branch(chain_id,locator)->Some(chain_id,locator)|_->None)(fun(chain_id,locator)->Current_branch(chain_id,locator));case~tag:0x12~title:"Deactivate"(obj1(req"deactivate"Chain_id.encoding))(functionDeactivatechain_id->Somechain_id|_->None)(funchain_id->Deactivatechain_id);case~tag:0x13~title:"Get_current_head"(obj1(req"get_current_head"Chain_id.encoding))(functionGet_current_headchain_id->Somechain_id|_->None)(funchain_id->Get_current_headchain_id);case~tag:0x14~title:"Current_head"(obj3(req"chain_id"Chain_id.encoding)(req"current_block_header"(dynamic_sizeBounded_encoding.block_header))(req"current_mempool"Bounded_encoding.mempool))(function|Current_head(chain_id,bh,mempool)->Some(chain_id,bh,mempool)|_->None)(fun(chain_id,bh,mempool)->Current_head(chain_id,bh,mempool));case~tag:0x20~title:"Get_block_headers"(obj1(req"get_block_headers"(list~max_length:10Block_hash.encoding)))(functionGet_block_headersbhs->Somebhs|_->None)(funbhs->Get_block_headersbhs);case~tag:0x21~title:"Block_header"(obj1(req"block_header"Bounded_encoding.block_header))(functionBlock_headerbh->Somebh|_->None)(funbh->Block_headerbh);case~tag:0x30~title:"Get_operations"(obj1(req"get_operations"(list~max_length:10Operation_hash.encoding)))(functionGet_operationsbhs->Somebhs|_->None)(funbhs->Get_operationsbhs);case~tag:0x31~title:"Operation"(obj1(req"operation"Bounded_encoding.operation))(functionOperationo->Someo|_->None)(funo->Operationo);case~tag:0x40~title:"Get_protocols"(obj1(req"get_protocols"(list~max_length:10Protocol_hash.encoding)))(functionGet_protocolsprotos->Someprotos|_->None)(funprotos->Get_protocolsprotos);case~tag:0x41~title:"Protocol"(obj1(req"protocol"Bounded_encoding.protocol))(functionProtocolproto->Someproto|_->None)(funproto->Protocolproto);case~tag:0x60~title:"Get_operations_for_blocks"(obj1(req"get_operations_for_blocks"(list~max_length:10(obj2(req"hash"Block_hash.encoding)(req"validation_pass"int8)))))(functionGet_operations_for_blockskeys->Somekeys|_->None)(funkeys->Get_operations_for_blockskeys);case~tag:0x61~title:"Operations_for_blocks"(merge_objs(obj1(req"operations_for_block"(obj2(req"hash"Block_hash.encoding)(req"validation_pass"int8))))Bounded_encoding.operation_list)(function|Operations_for_block(block,ofs,ops,path)->Some((block,ofs),(path,ops))|_->None)(fun((block,ofs),(path,ops))->Operations_for_block(block,ofs,ops,path));case~tag:0x70~title:"Get_checkpoint"(obj1(req"get_checkpoint"Chain_id.encoding))(functionGet_checkpointchain->Somechain|_->None)(funchain->Get_checkpointchain);case~tag:0x71~title:"Checkpoint"(obj1(req"checkpoint"(obj2(req"chain_id"Chain_id.encoding)(req"header"Bounded_encoding.block_header))))(function|Checkpoint(chain_id,header)->Some(chain_id,header)|_->None)(fun(chain_id,header)->Checkpoint(chain_id,header));case~tag:0x80~title:"Get_protocol_branch"(obj1(req"get_protocol_branch"(obj2(req"chain"Chain_id.encoding)(req"proto_level"uint8))))(function|Get_protocol_branch(chain,protocol)->Some(chain,protocol)|_->None)(fun(chain,protocol)->Get_protocol_branch(chain,protocol));case~tag:0x81~title:"Protocol_branch"(obj1(req"protocol_branch"(obj3(req"chain"Chain_id.encoding)(req"proto_level"uint8)(req"locator"Bounded_encoding.block_locator))))(function|Protocol_branch(chain,proto_level,locator)->Some(chain,proto_level,locator)|_->None)(fun(chain,proto_level,locator)->Protocol_branch(chain,proto_level,locator));case~tag:0x90~title:"Get_predecessor_header"(obj1(req"get_predecessor_header"(obj2(req"block"Block_hash.encoding)(req"offset"int32))))(function|Get_predecessor_header(block,offset)->Some(block,offset)|_->None)(fun(block,offset)->Get_predecessor_header(block,offset));case~tag:0x91~title:"Predecessor_header"(obj1(req"predecessor_header"(obj3(req"block"Block_hash.encoding)(req"offset"int32)(req"header"Bounded_encoding.block_header))))(function|Predecessor_header(hash,offset,header)->Some(hash,offset,header)|_->None)(fun(hash,offset,header)->Predecessor_header(hash,offset,header));]letdistributed_db_versions=Distributed_db_version.[zero;one;two]letcfgchain_name:_P2p_params.message_config={encoding;chain_name;distributed_db_versions}letraw_encoding=P2p_message.encodingencodingletpp_jsonppfmsg=Data_encoding.Json.ppppf(Data_encoding.Json.constructraw_encoding(Messagemsg))