123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878(*****************************************************************************)(* *)(* 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. *)(* *)(*****************************************************************************)openStorage_sigsmoduleMake_encoder(V:VALUE)=structletof_bytes~keyb=matchData_encoding.Binary.of_bytesV.encodingbwith|None->Error[Raw_context.Storage_error(Corrupted_datakey)]|Somev->Okvletto_bytesv=matchData_encoding.Binary.to_bytesV.encodingvwith|Someb->b|None->MBytes.create0endletlen_name="len"letdata_name="data"letencode_len_valuebytes=letlength=MBytes.lengthbytesinData_encoding.(Binary.to_bytes_exnint31)lengthletdecode_len_valuekeylen=matchData_encoding.(Binary.of_bytesint31)lenwith|None->fail(Raw_context.Storage_error(Corrupted_datakey))|Somelen->returnlenletmap_keyf=function|`Keyk->`Key(fk)|`Dirk->`Dir(fk)moduleMake_subcontext(C:Raw_context.T)(N:NAME):Raw_context.Twithtypet=C.t=structtypet=C.ttypecontext=tletname_length=List.lengthN.nameletto_keyk=N.name@kletof_keyk=Misc.remove_elem_from_listname_lengthkletmemtk=C.memt(to_keyk)letdir_memtk=C.dir_memt(to_keyk)letgettk=C.gett(to_keyk)letget_optiontk=C.get_optiont(to_keyk)letinittkv=C.initt(to_keyk)vletsettkv=C.sett(to_keyk)vletinit_settkv=C.init_sett(to_keyk)vletset_optiontkv=C.set_optiont(to_keyk)vletdeletetk=C.deletet(to_keyk)letremovetk=C.removet(to_keyk)letremove_rectk=C.remove_rect(to_keyk)letcopyt~from~to_=C.copyt~from:(to_keyfrom)~to_:(to_keyto_)letfoldtk~init~f=C.foldt(to_keyk)~init~f:(funkacc->f(map_keyof_keyk)acc)letkeystk=C.keyst(to_keyk)>|=funkeys->List.mapof_keykeysletfold_keystk~init~f=C.fold_keyst(to_keyk)~init~f:(funkacc->f(of_keyk)acc)letproject=C.projectletabsolute_keyck=C.absolute_keyc(to_keyk)letconsume_gas=C.consume_gasletcheck_enough_gas=C.check_enough_gasletdescription=Storage_description.register_named_subcontextC.descriptionN.nameendmoduleMake_single_data_storage(C:Raw_context.T)(N:NAME)(V:VALUE):Single_data_storagewithtypet=C.tandtypevalue=V.t=structtypet=C.ttypecontext=ttypevalue=V.tletmemt=C.memtN.nameincludeMake_encoder(V)letgett=C.gettN.name>>=?funb->letkey=C.absolute_keytN.nameinLwt.return(of_bytes~keyb)letget_optiont=C.get_optiontN.name>>=function|None->return_none|Someb->letkey=C.absolute_keytN.nameinmatchof_bytes~keybwith|Okv->return_somev|Error_aserr->Lwt.returnerrletinittv=C.inittN.name(to_bytesv)>>=?funt->return(C.projectt)letsettv=C.settN.name(to_bytesv)>>=?funt->return(C.projectt)letinit_settv=C.init_settN.name(to_bytesv)>>=funt->Lwt.return(C.projectt)letset_optiontv=C.set_optiontN.name(Option.map~f:to_bytesv)>>=funt->Lwt.return(C.projectt)letremovet=C.removetN.name>>=funt->Lwt.return(C.projectt)letdeletet=C.deletetN.name>>=?funt->return(C.projectt)let()=letopenStorage_descriptioninregister_value~get:get_option(register_named_subcontextC.descriptionN.name)V.encodingendmoduletypeINDEX=sigtypetvalpath_length:intvalto_path:t->stringlist->stringlistvalof_path:stringlist->toptiontype'aipathvalargs:('a,t,'aipath)Storage_description.argsendmodulePair(I1:INDEX)(I2:INDEX):INDEXwithtypet=I1.t*I2.t=structtypet=I1.t*I2.tletpath_length=I1.path_length+I2.path_lengthletto_path(x,y)l=I1.to_pathx(I2.to_pathyl)letof_pathl=matchMisc.takeI1.path_lengthlwith|None->None|Some(l1,l2)->matchI1.of_pathl1,I2.of_pathl2with|Somex,Somey->Some(x,y)|_->Nonetype'aipath='aI1.ipathI2.ipathletargs=Storage_description.Pair(I1.args,I2.args)endmoduleMake_data_set_storage(C:Raw_context.T)(I:INDEX):Data_set_storagewithtypet=C.tandtypeelt=I.t=structtypet=C.ttypecontext=ttypeelt=I.tletinited=MBytes.of_string"inited"letmemsi=C.mems(I.to_pathi[])letaddsi=C.init_sets(I.to_pathi[])inited>>=funt->Lwt.return(C.projectt)letdelsi=C.removes(I.to_pathi[])>>=funt->Lwt.return(C.projectt)letsetsi=function|true->addsi|false->delsiletclears=C.remove_recs[]>>=funt->Lwt.return(C.projectt)letfolds~init~f=letrecdigipathacc=ifCompare.Int.(i<=1)thenC.foldspath~init:acc~f:beginfunkacc->matchkwith|`Dir_->Lwt.returnacc|`Keyfile->matchI.of_pathfilewith|None->assertfalse|Somep->fpaccendelseC.foldspath~init:acc~f:beginfunkacc->matchkwith|`Dirk->dig(i-1)kacc|`Key_->Lwt.returnaccendindigI.path_length[]initletelementss=folds~init:[]~f:(funpacc->Lwt.return(p::acc))let()=letopenStorage_descriptioninletunpack=unpackI.argsinregister_value(* TODO fixme 'elements...' *)~get:(func->let(c,k)=unpackcinmemck>>=function|true->return_sometrue|false->return_none)(register_indexed_subcontext~list:(func->elementsc>>=return)C.descriptionI.args)Data_encoding.boolendmoduleMake_indexed_data_storage(C:Raw_context.T)(I:INDEX)(V:VALUE):Indexed_data_storagewithtypet=C.tandtypekey=I.tandtypevalue=V.t=structtypet=C.ttypecontext=ttypekey=I.ttypevalue=V.tincludeMake_encoder(V)letmemsi=C.mems(I.to_pathi[])letgetsi=C.gets(I.to_pathi[])>>=?funb->letkey=C.absolute_keys(I.to_pathi[])inLwt.return(of_bytes~keyb)letget_optionsi=C.get_options(I.to_pathi[])>>=function|None->return_none|Someb->letkey=C.absolute_keys(I.to_pathi[])inmatchof_bytes~keybwith|Okv->return_somev|Error_aserr->Lwt.returnerrletsetsiv=C.sets(I.to_pathi[])(to_bytesv)>>=?funt->return(C.projectt)letinitsiv=C.inits(I.to_pathi[])(to_bytesv)>>=?funt->return(C.projectt)letinit_setsiv=C.init_sets(I.to_pathi[])(to_bytesv)>>=funt->Lwt.return(C.projectt)letset_optionsiv=C.set_options(I.to_pathi[])(Option.map~f:to_bytesv)>>=funt->Lwt.return(C.projectt)letremovesi=C.removes(I.to_pathi[])>>=funt->Lwt.return(C.projectt)letdeletesi=C.deletes(I.to_pathi[])>>=?funt->return(C.projectt)letclears=C.remove_recs[]>>=funt->Lwt.return(C.projectt)letfold_keyss~init~f=letrecdigipathacc=ifCompare.Int.(i<=1)thenC.foldspath~init:acc~f:beginfunkacc->matchkwith|`Dir_->Lwt.returnacc|`Keyfile->matchI.of_pathfilewith|None->assertfalse|Somepath->fpathaccendelseC.foldspath~init:acc~f:beginfunkacc->matchkwith|`Dirk->dig(i-1)kacc|`Key_->Lwt.returnaccendindigI.path_length[]initletfolds~init~f=letfpathacc=getspath>>=function|Error_->(* FIXME: silently ignore unparsable data *)Lwt.returnacc|Okv->fpathvaccinfold_keyss~init~fletbindingss=folds~init:[]~f:(funpvacc->Lwt.return((p,v)::acc))letkeyss=fold_keyss~init:[]~f:(funpacc->Lwt.return(p::acc))let()=letopenStorage_descriptioninletunpack=unpackI.argsinregister_value~get:(func->let(c,k)=unpackcinget_optionck)(register_indexed_subcontext~list:(func->keysc>>=return)C.descriptionI.args)V.encodingendmoduleMake_indexed_carbonated_data_storage(C:Raw_context.T)(I:INDEX)(V:VALUE):Non_iterable_indexed_carbonated_data_storagewithtypet=C.tandtypekey=I.tandtypevalue=V.t=structtypet=C.ttypecontext=ttypekey=I.ttypevalue=V.tincludeMake_encoder(V)letnamei=I.to_pathi[data_name]letlen_namei=I.to_pathi[len_name]letconsume_mem_gasc=Lwt.return(C.consume_gasc(Gas_limit_repr.read_bytes_costZ.zero))letexisting_sizeci=C.get_optionc(len_namei)>>=function|None->return0|Somelen->decode_len_value(len_namei)lenletconsume_read_gasgetci=getc(len_namei)>>=?funlen->decode_len_value(len_namei)len>>=?funlen->Lwt.return(C.consume_gasc(Gas_limit_repr.read_bytes_cost(Z.of_intlen)))letconsume_serialize_write_gassetciv=letbytes=to_bytesvinletlen=MBytes.lengthbytesinLwt.return(C.consume_gasc(Gas_limit_repr.alloc_mbytes_costlen))>>=?func->Lwt.return(C.consume_gasc(Gas_limit_repr.write_bytes_cost(Z.of_intlen)))>>=?func->setc(len_namei)(encode_len_valuebytes)>>=?func->return(c,bytes)letconsume_remove_gasdelci=Lwt.return(C.consume_gasc(Gas_limit_repr.write_bytes_costZ.zero))>>=?func->delc(len_namei)letmemsi=consume_mem_gass>>=?funs->C.mems(namei)>>=funexists->return(C.projects,exists)letgetsi=consume_read_gasC.getsi>>=?funs->C.gets(namei)>>=?funb->letkey=C.absolute_keys(namei)inLwt.return(of_bytes~keyb)>>=?funv->return(C.projects,v)letget_optionsi=consume_mem_gass>>=?funs->C.mems(namei)>>=funexists->ifexiststhengetsi>>=?fun(s,v)->return(s,Somev)elsereturn(C.projects,None)letsetsiv=existing_sizesi>>=?funprev_size->consume_serialize_write_gasC.setsiv>>=?fun(s,bytes)->C.sets(namei)bytes>>=?funt->letsize_diff=MBytes.lengthbytes-prev_sizeinreturn(C.projectt,size_diff)letinitsiv=consume_serialize_write_gasC.initsiv>>=?fun(s,bytes)->C.inits(namei)bytes>>=?funt->letsize=MBytes.lengthbytesinreturn(C.projectt,size)letinit_setsiv=letinit_setsiv=C.init_setsiv>>=returninexisting_sizesi>>=?funprev_size->consume_serialize_write_gasinit_setsiv>>=?fun(s,bytes)->init_sets(namei)bytes>>=?funt->letsize_diff=MBytes.lengthbytes-prev_sizeinreturn(C.projectt,size_diff)letremovesi=letremovesi=C.removesi>>=returninexisting_sizesi>>=?funprev_size->consume_remove_gasremovesi>>=?funs->removes(namei)>>=?funt->return(C.projectt,prev_size)letdeletesi=existing_sizesi>>=?funprev_size->consume_remove_gasC.deletesi>>=?funs->C.deletes(namei)>>=?funt->return(C.projectt,prev_size)letset_optionsiv=matchvwith|None->removesi|Somev->init_setsivletfold_keys_unaccounteds~init~f=letrecdigipathacc=ifCompare.Int.(i<=1)thenC.foldspath~init:acc~f:beginfunkacc->matchkwith|`Dir_->Lwt.returnacc|`Keyfile->matchI.of_pathfilewith|None->assertfalse|Somepath->fpathaccendelseC.foldspath~init:acc~f:beginfunkacc->matchkwith|`Dirk->dig(i-1)kacc|`Key_->Lwt.returnaccendindigI.path_length[data_name]initletkeys_unaccounteds=fold_keys_unaccounteds~init:[]~f:(funpacc->Lwt.return(p::acc))let()=letopenStorage_descriptioninletunpack=unpackI.argsinregister_value(* TODO export consumed gas ?? *)~get:(func->let(c,k)=unpackcinget_optionck>>=?fun(_,v)->returnv)(register_indexed_subcontext~list:(func->keys_unaccountedc>>=return)C.descriptionI.args)V.encodingendmoduleMake_indexed_data_snapshotable_storage(C:Raw_context.T)(Snapshot_index:INDEX)(I:INDEX)(V:VALUE):Indexed_data_snapshotable_storagewithtypet=C.tandtypesnapshot=Snapshot_index.tandtypekey=I.tandtypevalue=V.t=structtypesnapshot=Snapshot_index.tletdata_name=["current"]letsnapshot_name=["snapshot"]moduleC_data=Make_subcontext(C)(structletname=data_nameend)moduleC_snapshot=Make_subcontext(C)(structletname=snapshot_nameend)includeMake_indexed_data_storage(C_data)(I)(V)moduleSnapshot=Make_indexed_data_storage(C_snapshot)(Pair(Snapshot_index)(I))(V)letsnapshot_pathid=snapshot_name@Snapshot_index.to_pathid[]letsnapshot_existssid=C.dir_mems(snapshot_pathid)letsnapshotsid=C.copys~from:data_name~to_:(snapshot_pathid)>>=?funt->return(C.projectt)letdelete_snapshotsid=C.remove_recs(snapshot_pathid)>>=funt->Lwt.return(C.projectt)endmoduleMake_indexed_subcontext(C:Raw_context.T)(I:INDEX):Indexed_raw_contextwithtypet=C.tandtypekey=I.tandtype'aipath='aI.ipath=structtypet=C.ttypecontext=ttypekey=I.ttype'aipath='aI.ipathletcleart=C.remove_rect[]>>=funt->Lwt.return(C.projectt)letfold_keyst~init~f=letrecdigipathacc=ifCompare.Int.(i<=0)thenmatchI.of_pathpathwith|None->assertfalse|Somepath->fpathaccelseC.foldtpath~init:acc~f:beginfunkacc->matchkwith|`Dirk->dig(i-1)kacc|`Key_->Lwt.returnaccendindigI.path_length[]initletkeyst=fold_keyst~init:[]~f:(funiacc->Lwt.return(i::acc))letlisttk=C.foldtk~init:[]~f:(funkacc->Lwt.return(k::acc))letdescription=Storage_description.register_indexed_subcontext~list:(func->keysc>>=return)C.descriptionI.argsletunpack=Storage_description.unpackI.argsletpack=Storage_description.packI.argsmoduleRaw_context=structtypet=C.tI.ipathtypecontext=tletto_keyik=I.to_pathikletof_keyk=Misc.remove_elem_from_listI.path_lengthkletmemck=let(t,i)=unpackcinC.memt(to_keyik)letdir_memck=let(t,i)=unpackcinC.dir_memt(to_keyik)letgetck=let(t,i)=unpackcinC.gett(to_keyik)letget_optionck=let(t,i)=unpackcinC.get_optiont(to_keyik)letinitckv=let(t,i)=unpackcinC.initt(to_keyik)v>>=?funt->return(packti)letsetckv=let(t,i)=unpackcinC.sett(to_keyik)v>>=?funt->return(packti)letinit_setckv=let(t,i)=unpackcinC.init_sett(to_keyik)v>>=funt->Lwt.return(packti)letset_optionckv=let(t,i)=unpackcinC.set_optiont(to_keyik)v>>=funt->Lwt.return(packti)letdeleteck=let(t,i)=unpackcinC.deletet(to_keyik)>>=?funt->return(packti)letremoveck=let(t,i)=unpackcinC.removet(to_keyik)>>=funt->Lwt.return(packti)letremove_recck=let(t,i)=unpackcinC.remove_rect(to_keyik)>>=funt->Lwt.return(packti)letcopyc~from~to_=let(t,i)=unpackcinC.copyt~from:(to_keyifrom)~to_:(to_keyito_)>>=?funt->return(packti)letfoldck~init~f=let(t,i)=unpackcinC.foldt(to_keyik)~init~f:(funkacc->f(map_keyof_keyk)acc)letkeysck=let(t,i)=unpackcinC.keyst(to_keyik)>|=funkeys->List.mapof_keykeysletfold_keysck~init~f=let(t,i)=unpackcinC.fold_keyst(to_keyik)~init~f:(funkacc->f(of_keyk)acc)letprojectc=let(t,_)=unpackcinC.projecttletabsolute_keyck=let(t,i)=unpackcinC.absolute_keyt(to_keyik)letconsume_gascg=let(t,i)=unpackcinC.consume_gastg>>?funt->ok(packti)letcheck_enough_gascg=let(t,_i)=unpackcinC.check_enough_gastgletdescription=descriptionendletresolvetprefix=letrecloopiprefix=function|[]whenCompare.Int.(i=I.path_length)->beginmatchI.of_pathprefixwith|None->assertfalse|Somepath->Lwt.return[path]end|[]->listtprefix>>=funprefixes->Lwt_list.map_p(function|`Keyprefix|`Dirprefix->loop(i+1)prefix[])prefixes>|=List.flatten|[d]whenCompare.Int.(i=I.path_length-1)->ifCompare.Int.(i>=I.path_length)theninvalid_arg"IO.resolve";listtprefix>>=funprefixes->Lwt_list.map_p(function|`Keyprefix|`Dirprefix->matchMisc.remove_prefix~prefix:d(List.hd(List.revprefix))with|None->Lwt.return_nil|Some_->loop(i+1)prefix[])prefixes>|=List.flatten|""::ds->listtprefix>>=funprefixes->Lwt_list.map_p(function|`Keyprefix|`Dirprefix->loop(i+1)prefixds)prefixes>|=List.flatten|d::ds->ifCompare.Int.(i>=I.path_length)theninvalid_arg"IO.resolve";C.dir_memt(prefix@[d])>>=function|true->loop(i+1)(prefix@[d])ds|false->Lwt.return_nilinloop0[]prefixmoduleMake_set(N:NAME)=structtypet=C.ttypecontext=ttypeelt=I.tletinited=MBytes.of_string"inited"letmemsi=Raw_context.mem(packsi)N.nameletaddsi=Raw_context.init_set(packsi)N.nameinited>>=func->let(s,_)=unpackcinLwt.return(C.projects)letdelsi=Raw_context.remove(packsi)N.name>>=func->let(s,_)=unpackcinLwt.return(C.projects)letsetsi=function|true->addsi|false->delsiletclears=fold_keyss~init:s~f:beginfunis->Raw_context.remove(packsi)N.name>>=func->let(s,_)=unpackcinLwt.returnsend>>=funt->Lwt.return(C.projectt)letfolds~init~f=fold_keyss~init~f:(funiacc->memsi>>=function|true->fiacc|false->Lwt.returnacc)letelementss=folds~init:[]~f:(funpacc->Lwt.return(p::acc))let()=letopenStorage_descriptioninletunpack=unpackI.argsinregister_value~get:(func->let(c,k)=unpackcinmemck>>=function|true->return_sometrue|false->return_none)(register_named_subcontextRaw_context.descriptionN.name)Data_encoding.boolendmoduleMake_map(N:NAME)(V:VALUE)=structtypet=C.ttypecontext=ttypekey=I.ttypevalue=V.tincludeMake_encoder(V)letmemsi=Raw_context.mem(packsi)N.nameletgetsi=Raw_context.get(packsi)N.name>>=?funb->letkey=Raw_context.absolute_key(packsi)N.nameinLwt.return(of_bytes~keyb)letget_optionsi=Raw_context.get_option(packsi)N.name>>=function|None->return_none|Someb->letkey=Raw_context.absolute_key(packsi)N.nameinmatchof_bytes~keybwith|Okv->return_somev|Error_aserr->Lwt.returnerrletsetsiv=Raw_context.set(packsi)N.name(to_bytesv)>>=?func->let(s,_)=unpackcinreturn(C.projects)letinitsiv=Raw_context.init(packsi)N.name(to_bytesv)>>=?func->let(s,_)=unpackcinreturn(C.projects)letinit_setsiv=Raw_context.init_set(packsi)N.name(to_bytesv)>>=func->let(s,_)=unpackcinLwt.return(C.projects)letset_optionsiv=Raw_context.set_option(packsi)N.name(Option.map~f:to_bytesv)>>=func->let(s,_)=unpackcinLwt.return(C.projects)letremovesi=Raw_context.remove(packsi)N.name>>=func->let(s,_)=unpackcinLwt.return(C.projects)letdeletesi=Raw_context.delete(packsi)N.name>>=?func->let(s,_)=unpackcinreturn(C.projects)letclears=fold_keyss~init:s~f:beginfunis->Raw_context.remove(packsi)N.name>>=func->let(s,_)=unpackcinLwt.returnsend>>=funt->Lwt.return(C.projectt)letfolds~init~f=fold_keyss~init~f:(funiacc->getsi>>=function|Error_->Lwt.returnacc|Okv->fivacc)letbindingss=folds~init:[]~f:(funpvacc->Lwt.return((p,v)::acc))letfold_keyss~init~f=fold_keyss~init~f:(funiacc->memsi>>=function|false->Lwt.returnacc|true->fiacc)letkeyss=fold_keyss~init:[]~f:(funpacc->Lwt.return(p::acc))let()=letopenStorage_descriptioninletunpack=unpackI.argsinregister_value~get:(func->let(c,k)=unpackcinget_optionck)(register_named_subcontextRaw_context.descriptionN.name)V.encodingendmoduleMake_carbonated_map(N:NAME)(V:VALUE)=structtypet=C.ttypecontext=ttypekey=I.ttypevalue=V.tincludeMake_encoder(V)letlen_name=len_name::N.nameletdata_name=data_name::N.nameletconsume_mem_gasc=Lwt.return(Raw_context.consume_gasc(Gas_limit_repr.read_bytes_costZ.zero))letexisting_sizec=Raw_context.get_optionclen_name>>=function|None->return0|Somelen->decode_len_valuelen_namelenletconsume_read_gasgetc=getc(len_name)>>=?funlen->decode_len_valuelen_namelen>>=?funlen->Lwt.return(Raw_context.consume_gasc(Gas_limit_repr.read_bytes_cost(Z.of_intlen)))letconsume_write_gassetcv=letbytes=to_bytesvinletlen=MBytes.lengthbytesinLwt.return(Raw_context.consume_gasc(Gas_limit_repr.write_bytes_cost(Z.of_intlen)))>>=?func->setclen_name(encode_len_valuebytes)>>=?func->return(c,bytes)letconsume_remove_gasdelc=Lwt.return(Raw_context.consume_gasc(Gas_limit_repr.write_bytes_costZ.zero))>>=?func->delclen_nameletmemsi=consume_mem_gas(packsi)>>=?func->Raw_context.memcdata_name>>=funres->return(Raw_context.projectc,res)letgetsi=consume_read_gasRaw_context.get(packsi)>>=?func->Raw_context.getcdata_name>>=?funb->letkey=Raw_context.absolute_keycdata_nameinLwt.return(of_bytes~keyb)>>=?funv->return(Raw_context.projectc,v)letget_optionsi=consume_mem_gas(packsi)>>=?func->let(s,_)=unpackcinRaw_context.mem(packsi)data_name>>=funexists->ifexiststhengetsi>>=?fun(s,v)->return(s,Somev)elsereturn(C.projects,None)letsetsiv=existing_size(packsi)>>=?funprev_size->consume_write_gasRaw_context.set(packsi)v>>=?fun(c,bytes)->Raw_context.setcdata_namebytes>>=?func->letsize_diff=MBytes.lengthbytes-prev_sizeinreturn(Raw_context.projectc,size_diff)letinitsiv=consume_write_gasRaw_context.init(packsi)v>>=?fun(c,bytes)->Raw_context.initcdata_namebytes>>=?func->letsize=MBytes.lengthbytesinreturn(Raw_context.projectc,size)letinit_setsiv=letinit_setckv=Raw_context.init_setckv>>=returninexisting_size(packsi)>>=?funprev_size->consume_write_gasinit_set(packsi)v>>=?fun(c,bytes)->init_setcdata_namebytes>>=?func->letsize_diff=MBytes.lengthbytes-prev_sizeinreturn(Raw_context.projectc,size_diff)letremovesi=letremoveck=Raw_context.removeck>>=returninexisting_size(packsi)>>=?funprev_size->consume_remove_gasremove(packsi)>>=?func->removecdata_name>>=?func->return(Raw_context.projectc,prev_size)letdeletesi=existing_size(packsi)>>=?funprev_size->consume_remove_gasRaw_context.delete(packsi)>>=?func->Raw_context.deletecdata_name>>=?func->return(Raw_context.projectc,prev_size)letset_optionsiv=matchvwith|None->removesi|Somev->init_setsivlet()=letopenStorage_descriptioninletunpack=unpackI.argsinregister_value~get:(func->let(c,k)=unpackcinget_optionck>>=?fun(_,v)->returnv)(register_named_subcontextRaw_context.descriptionN.name)V.encodingendendmoduleWrap_indexed_data_storage(C:Indexed_data_storage)(K:sigtypetvalwrap:t->C.keyvalunwrap:C.key->toptionend)=structtypet=C.ttypecontext=C.ttypekey=K.ttypevalue=C.valueletmemctxtk=C.memctxt(K.wrapk)letgetctxtk=C.getctxt(K.wrapk)letget_optionctxtk=C.get_optionctxt(K.wrapk)letsetctxtkv=C.setctxt(K.wrapk)vletinitctxtkv=C.initctxt(K.wrapk)vletinit_setctxtkv=C.init_setctxt(K.wrapk)vletset_optionctxtkv=C.set_optionctxt(K.wrapk)vletdeletectxtk=C.deletectxt(K.wrapk)letremovectxtk=C.removectxt(K.wrapk)letclearctxt=C.clearctxtletfoldctxt~init~f=C.foldctxt~init~f:(funkvacc->matchK.unwrapkwith|None->Lwt.returnacc|Somek->fkvacc)letbindingss=folds~init:[]~f:(funpvacc->Lwt.return((p,v)::acc))letfold_keyss~init~f=C.fold_keyss~init~f:(funkacc->matchK.unwrapkwith|None->Lwt.returnacc|Somek->fkacc)letkeyss=fold_keyss~init:[]~f:(funpacc->Lwt.return(p::acc))end