diff --git a/Cargo.lock b/Cargo.lock index a266b4d..07757d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1082,7 +1082,7 @@ dependencies = [ [[package]] name = "parlia-elc" -version = "0.3.0" +version = "0.2.9" dependencies = [ "elliptic-curve", "hex-literal", diff --git a/light-client/Cargo.toml b/light-client/Cargo.toml index 35dec2c..fb99e74 100644 --- a/light-client/Cargo.toml +++ b/light-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parlia-elc" -version = "0.3.0" +version = "0.2.9" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/light-client/src/client.rs b/light-client/src/client.rs index cbe17de..07ae57e 100644 --- a/light-client/src/client.rs +++ b/light-client/src/client.rs @@ -472,7 +472,7 @@ mod test { } #[test] - fn test_success_update_state_epoch() { + fn test_success_update_state_neighboring_epoch() { let header = hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212b2520ab3110ab011f908ada0c1b3a1b35c53d9860d1464d20138e6271602e00ea876757d7106016ce83466f3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ef0274e31810c9df02f98fafde0f841f4e66a1cda0db01e241c7ed90c7fafad6ebbd727b14b7633bd336a97fc9761bc37b12aad0f4a0cc1257fae1a1a2648190df64c111671f764e7729157d87a6a75046060e937d53a0791ba98205dc99116e137099424fe843a0765cb96f82d2c597a43da570355351b9010003b2fbb5134f56fe987ffbd6bf693df76b135948febbc7f808dea7f70e3a59a2d7f8bdeed8263f57c7d336fd0bdf3ff9df186a1e557df4edd987f8fefeafa6f0e4f385ed7df6bffd57c1d75f5a8e95fe7ff45b2588f66cfc8affdfd4decc77d8f6feb97f2ad701308ff50f677fe79af5ae4cd4fae8c7ed0cd7fdcc3cd0d3feaf976ec2daebddaa766d8d9e689ff7f7bfbf646fa72897dfcedff9b57bf9cb1ff1e378ca85df3607bcaf2b65dc7fc68dfefe3f1ea73cfff9174ad7e82f73ed7ff3e4a09f9fd97d794777aadfecdbcb77bf7b7ffcbbdff4615c4314fbfedb6ff68959f3fa71efdcd44bff3e6f44b655e388bfd4bcf8fa11a95f67fbfff8eb2af9cd028402211e008408583b0084011b48aa8465ba3192b906add883010307846765746888676f312e32302e35856c696e757800000001a091a0150bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a61dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d25685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d35872b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a517ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e8b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694859bb832254baf4e8b4cc26bd2b52b31389b56e98bab764a39ff81dad720d5691b852898041a3842e09ecbac8025812d51b32223d8420e6ae51a01582220a10f7722de67c1a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b741b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de7b4dd66d7c2c7e57f628210187192fb89d4b99dd4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cdcc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a419ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbbd1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce739e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d21ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c192183ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5bef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0f8b5831bdbffb860a1b2529dc7c1cb57e9b80a29d82ca0fafad5245fb7947158cc585b96609a8dfd005f2b9d111cad1d663d506cfc8a2cd2111831cb0863c5a92007a91dc504a32e496d6e3e392258e7fd47d0ed7e01a8448a1f9967fae814829c4104b2d2f27b9df84c8402211dfea0567d4dd0ea048881bb924343a4e69bd8164a03ab881739dd0ce5cde9c3ab13408402211dffa0c1b3a1b35c53d9860d1464d20138e6271602e00ea876757d7106016ce83466f380e863967543e27479ee79f33ab2ee5e276b0970a1565d96767e3ff55ab16ce0ac421983faa09eea6aa8e769fdf8182251e9225e39b3feef23a302ba897c41d20c01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9e060a9b06f90318a029bf36156df8e525f809db876705baae274b69205fd5716448392648e0941c52a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794295e26495cef6f69dfa69911d9d8e4f3bbadb89ba06f43ef7855ea56f036992abd7d992004d9fb11c0f16ac7efad79698cfd468c55a048f43cb851c8a35dcaaa6216f8f041da9e548f6b699b3b60bd095409044c4542a0f5ca7a7a61593ea62df7e100ea541399629e3f3f90975ae4127c2cf46670f029b90100f93e770a65dbd3dedfe67ddcfad59d7bdc5ca5259f7eb5bd97efe35b4667e55aee7cdd8bf2715d8b3baf7dbbd73fa3b3d11fd1790ebaece8ad723bd8c3bce78837acd76ef9e95c7cd5ecfffb97a21ff6b8f4a8f52af4687b60d65c6fbff7de78cfeed676fa37efb75effed979f5ceaec3cdefe7b4babee0f8a69e6f7de4ed8a5bbdafe8753ae8eef77cb363f7f7415bcfef79cfd35a7943e3b783fd2d9eb35ff6f7cd6b2b7cda77a7eefe6beff8725f1e7eb35dbd4f2b59e976768eaf7ff5e64f0f73fb2ccfd449ec7ebdfa6eff77333f5bfb7efcabe75beb7d2ff73e4b5ef1863f5a0333644d9f307f777fededc8199fd0eef6bbf5c1e7cf2afdfd9bf7f14a9028402211e018408583b00840108e73c8465ba3195b90118d983010307846765746889676f312e32302e3133856c696e7578000001a091a0f8b5831bdbffb860a79e04e92307a88aacdb97e1af9c99826690c90dc3fb83251f6506c48fb5a8c515ab7afc554408fa67b4251b9910545601d47524cd356d2c7a6cf23e7a857666a3ca20c7b26949815d00ad110a57486afb03ebbdc0e6ad6205efda248580eafff84c8402211dffa0c1b3a1b35c53d9860d1464d20138e6271602e00ea876757d7106016ce83466f38402211e00a029bf36156df8e525f809db876705baae274b69205fd5716448392648e0941c52800290f15f352f1012037a54e82bc7fcef239ba9bb867286089a287d100ecd737449b93ff0af15c13affebd5db2a6be4767192689e8bcc809b26b794d9a37468ec00a00000000000000000000000000000000000000000000000000000000000000000880000000000000000800a9d060a9a06f90317a024897fb02565f515fa9fbb541eae07a132473349842b34786a06ec2a0d6ea64ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942d4c407bbe49438ed859fe965b140dcf1aab71a9a0175af0ef466ba120d773ebb4e5cf28141d94efd6214e5bb9cde6ef206a3afbfda066cc81edf1fbd1f605d108d2b478fbe7bb0c38ee3e3e5650ae035efa563fd729a0e3431ac6ae4eee634fd6a1d6e45807789b94ea432bdf8f9f857545823798e824b901008e7ea3b3105f95d18ca860548c85a7efd518cfa69c238dbd4efebd9d241b25f1cc559715d455a3e533b036ad819aa6b19b695ea91c3b23cebd293dd0b2b6e0ec56458b681fe22f7d45eec13f82ae55b2eaf5fe7537677a8ab6641be7f43100c09eccb83e9a8fa79e8f2f853d47b34bdb194d8c61c8fb2e6f6af59c3ac658b8460f6bc24c028e2ac09b88ef42a9028cc03a3577c9af93d67beccf3771457b0bfa92d2112a9be46b607ebdc9e67a14dd0d6ebd1cf9c48b7738a67744b114f952d5a1227fc312292cce5ca1aea7c48a1830bbc5e00a95c934fbf350d5d69ea1ed3edfb3bd79b9c95528a33546f781dfebbc6056911153b0887ce359ef1c8ac9181a028402211e028408583b0083f9c3198465ba3198b90118d983010307846765746889676f312e32302e3132856c696e7578000001a091a0f8b5831bdbffb860a5654b7010dfdd178f3465135f42d28c9d435d60d0267f87b2581e1d7fafab606146fb70c620b1663b0d46e5d58ca1580913f76779e3c5ba65916db7cc73ccfb9a569e3165266c5ccf25240154aa60ff995327a2a8695a58d68b2105314ab370f84c8402211e00a029bf36156df8e525f809db876705baae274b69205fd5716448392648e0941c528402211e01a024897fb02565f515fa9fbb541eae07a132473349842b34786a06ec2a0d6ea64e801d548b699a7cee908420aac8d540a2de752823af731ec288b2774069730edecf3d4900535cf7714138d359177c9064e446a7730b9349b3d2ee0436b5072a855201a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080120510ffbb84111ab51df90eb2f90211a0890231389e1c4e6a2f6e5b8154ea372063ed7d917cf0d32d7a2cd21adfd06842a00ef48a4e0bae1cbb1a3caa52a05cd1bedf1e22dc50e680b85838b4c4157f06fda036e5ab2773e21147d9baff1b131278acc2c6d94fe9b23d9fcfd03723db7bc345a062e246491852309e16167a9d3bf7496bea6cf7fc68bdde6bac349afe27a228bba09bb79be4b97ec382e2f13c4e552e85c5e8712e4ce079a84a19aa5008200d5b76a0e731649692d47833e6cf7053d746ea42d495ba405c363e9b7d0c672c8c4481b9a0e9bc22e8fa15d085a68c3bd14b9a750d310e1680ac5bdfa386f850aaa67905b8a0c352465d5662ac5b77de54c34855ab9c4e808378ab1d645cf7a30a8cb51caf26a00f4cb91d858bb51b8a795863d9552e1f105f2e3fb37f1d161c1dae4b203a3c72a02e7905a411dbd014e64713312927471c4b1c3885fda3ed5888c0fb192e6de359a05e60aa49704b32fcbcd9543275600ba900547b31ddf446d55c527f09f0f5c6f4a08886a98f2e030a70ec24f9b1096b548005b64c88faf516361a2a694abff08ac7a0f072b67b389d8c065c6585b92a89bcbdb4440ae210060f7b98ac92d7b1e62f8ca0e8ee249f924ccd80781c6892e42a15c60da9175802153a0ac71650b02c13ee36a0a8632cd2f0beeb0f89b728d65d9ea803bdf0b12a5e3d27cbe5832e4ceff8735ba0b10c2c47b02cd583395fc5e70520bf57b97ea460f5fbf600049db152afa0ab4880f90211a00971b494845868a4a6f5a36939740537be16ccc185b7724bb249439267aaacc3a0ff26bff9727522f6773d888a48e2f444b020e62fce9bf0c6e15eafa0d7c3cb58a006aa21a0b04e596b5a4ebbb384309a489e876c1be7e7a2b02a584b4530d66925a03af99e922ded079114bf3a92f2a21d0a5dd131d15e0f3e01c6410974fbc3d8cca011114fc621c9378780c8ded766139c9c1c5f03a8de0747eb17bf337ea4a2ca2da0604f4775514cb56b34732652f20b49abd5c40ba4310353e3e0271a7194379e9fa00266443ed0582ea87a478be34336830356a001e40dc4a05d139348d794bc0ba0a0c8e7006ec197ab21c2409125cdcff2e78f29fea018eca902733c017f43ca794da0dcf51b76b1845f2b5bce3e5e2ecac30166b619ff1f18329ecfc49d1f3de50d06a037c89a9609e09d5b06e33b8abd35e3f9073bc6bced657355ff26a44a1fb0a361a08290bc67998f67791a82885a0cb0e81cac9f35e02388febf3952b7b5b79f8885a00f172f431296d1e299667720093d4d3ccd4ec7aeec24241ccdea49ea1688646ba021de7fd2dc90ac8bb698c0888ec4ff9c19f5e5748d46b49dd7238da60e7fc3c6a018c43df08c3e25d13db0b22ee521f3f450aca517916b5cd5219c86b49e49a044a00b8131712251baad84b82f2a44b8a4868ac8d87f03fb631130fce4be948ed9c1a068aaddcd50b8e792c89aecebcc859ec916ed530162583515aa71815f8542b4e180f90211a0c14274d28a2e70b696f18013ed25d6dbad53e4f055cc95d9a831c025c2ed9b01a0632636410cd51a3c53b184462e1e407a0422ec61d24118ffbf9aad2e0158d97aa016c98b9e76bb41d55d32c15e53ff870dce6db42be5e31d669c10f60b70409912a01400aa2f7e63dfa22e66c1096a7032502c24b261a52074dcdbaf7672d411c163a086ce70144b17c65c8a205f3dfd182959f0b1fd7f90143ad50e6999752832694ba0f8d20b759725fe897eb1f8987aff3e33e2bb00f32ebd4ccf2068a3fc89ca6080a044de2aff10255376ed36b22eff5590eb58d3ee54d0e4cc7eca4d22ee11bf7387a03b8d65e333aa13f8afa5982868e7f7890ba9e9d1e71f57b6d3a7ecee4482d028a07983b553b56cdc0305676f9622ff64df4ef45f1400af3a94ad08cdfa43c8a6f6a09bfea18d16df95e1dc70ce655d8bd283c900157317ac53c05931096c80967c93a0df5c3ffdaab83f24dc1c21b63a655880aaba83e13ba3037db17f53dab3ecd908a03e664ae0cd067a6ad7aaed8ba647c34e2cffde9104cf9d385f302c7fcd714f85a012e7260db92227621f4ed41a8e50582cfef95cbad9d1b22ff14b82d3c59d9241a0a42731a74edae14df8c52c748eefa4dc148b679ff88e26ece01a753247875154a0a9bf2ef8979a58da04857064c92f0ca860c12e1e1739a419faa1a7a179e6a575a0da31d47321bec6cec888e06e9182d2b579b470e53fdb241f1d7c78f88c65133f80f90211a07cd4b1279b228ef40481922604a05d005cf3e596efbb7eecc920460725ffc958a04d0eb9ce763d8b0bd7d77eb2c450b1d1a68fa9d4a39f74fca416ae8b021dc252a0c8d17bafc04d0578123e28fe318c024cd8ffc2919906c9a0827f1e790c63ca36a03ec45bc4463a145cf8c75f30f706e244a745a1b27283c92dd8e29bc787fabeeba041e3e5a0474e922690d384c4ab603cf6cae1c5333510c5489a0b9cebdf9eb16da0872a5c56d4ddcfab1473aa4b5187aec0cd9ad6be7316293ed93e330649e6948aa033e7f70da3e2514734dfd9f6e22139c326c409ef5a098342d0ca117baae919a4a09822c694761ebd9436d546b74cb8a3c333887e3794521ac7ea5fa7f130306265a08f93244365f1bbd3d34190af7531cf9eb3bc752f4a7b37e2454811675098be24a0329fd3766ca5e0ead8ad587c20aac5d344426a175907f80b2ed4f3eda8001873a0704b7adbf076be42c914ebb93045d9dba99269d719e72f716e5c82e1c4d30ed6a05827484fc8250b11323578d86af3b2d98db47949bd7fc670fe62ac6d8b2b29dca0c50f5090c95cf05867a259e409440a47bb221fc0ca50765ab452a3b448fa68dfa0ea739dbb4d387dfb6f0aa8f13a8eeae6aef55b21512cb046f5cf6bf142a61d79a02fd141d9061f06e999c896bbc7b1d4d652be24a710c4893e9d7fe7aa30f7cfeea0135be94cdf13c38d956f6e782ac6ace9b8cc40305249ac24dee470a8236e7e1280f90211a08d19750aa033c3351c90890a8f3ce2bde5f8be2b419c6f45115d5e6fa822ee47a0af80bd31da73dd38aa307ddaf4a3a4967139569111706d42284c59fd65e962c8a0feadc5dfc37b565bf229e9c73931d9f2274a762ccd3fad295ec327c6afef9525a0974634e6d38bbff1b17032a6566dbb3ff4d964ddf8fd9461cc13be120a4c79eea08d665f3fffbb6db4768102cb4c238b7082ea97f148ebe52a4a7e2aba26c7c537a0d9f11599f8cd8e41ea2799bc67598f702cf749be0a8990f096f8047fba2839b0a09be08e8044dc3057d056efbf1418467b516c8eb78b6d3c04aa69a7da735886a7a0f098ba0d8d2aa43642190af04c3fa97ecd8a2fdbeb5d6a2fa8eb1312176c763aa0a5aee8d8da8b6c01810834dee37121817b4a6889237bc060c1b78dae010ccb6da0495ff86cf6a6a9d9b043c204db77369e9e9d9767d6af4d963c05468983d12a2ba0a8e2263e1242397424b80e4e5303d95c34484426f63348c4346bc7d7878a8cbda02d6d70eda441d1c2383000a093400ade51ac7a04abc1aa99a7ce7b1624cb731ba0d6e684d598642afd2d7934c57123128ba3485dd00862b738e8f18355286f7423a0e09050c854d7a0d5bfcdd14f07043fed81662126e2701a4566c1d7a261900c71a03ac1f69f8e20a8792ea98d671e979a20b51ed4b37b40e2671dc05dc4d6653ce7a0598310e43fc8ee41ddd015d5d2764c7cd4959840260cfa7cef41dff52ac51db980f90211a0f87b60a82c2c32d5439e3199ad0c3a009a7f5474a027dac454b09effadd1fbefa016bb48376076116f468f16394fc6898356d00b458ed14b901461d1afafc89e65a03d50a67e8ec93696c35865d9f03814e95406c8d04e5decc320b9a24e5beee1baa042fe91ec49a406bb4a35b05a7fc518b915550848ba48afdea839969737e94d19a0fb5a2ac85aa55665e6a21b4d77a80693cfa450ad3db8e22963f12740f79e948ba0a32564adebb5029e48a91c8f6a90d04de2d3042b4a44f20e347bd68a26ab0cdda026c57b9b5218aee794dc9b3f90935ff1374ede5b73847c902ca61a1c41105e9aa02b22a7bb0d1b84b9d89fbfc571f0c4122bb12add28e944b047e40323fbbc33bda08a831384faa68f9caa047a6200464e11cfe5f9f700a5ed9435e5241d9d2a501ca08987636c0999e2eb3d052f145cd6b23f50946f6d737da20b5a7e2e1a8dc91c97a0e4fc7281b24a4a9d96dd4af6804d6276bc1c176d8e34979da2e7140310e66adaa06cf03705b25b817df44e3bc2122f8f49ca8aa80f32e7cfc5ed69f6c37ff49c2ea0dc66c764a34bf9f1c62917dbfcd1b930fd9b9c4379d520104519ab3e80f05265a004c43c3abc9e1ee7c131611fb29bf3e55705b91f687b5b30bdb6c5fccb431232a0dc32b4bb85eb8facf38af40cd4f77d9159f4723c939ac466e106a6d3c7535847a060dfd3aff904b5bb6d5f2e37695e05c9b935fab7888bc88486f6e811f606e20080f9015180a0c2cb770a3d18eb1214a782cc81b79a7fd772716c2d050ef66011095c3774e8f7a08fc7d7da06fba7ffa69b095aae41147e3a55b89644682057cedab705ba7aefd5a05975b434f69398107a4d1729f8f56e75247df09c65b1a750797818607bf118df80a026cea4c13260b2a1dd74bb6fcc7cc36162d2856ce691a36165c633ba68f7b783a0f7b0c667509a4ce937c487b45bc53c0700543daf4f8c127fbe475b4e1084d2328080a0454eca3fcc32afd4c4000ccbb47732bbce342b1a9d374fb5872162f2c873625fa0b3e6c44579a731cc730a5472e83c6098fa2943e5b2c72f4475f0afea76848a87a03b8c951788b8c93366aedbf88f6c1ca6085cd0249025ce542f19294b40bb92f180a06efa682f711f1d9e189193bd4248884cecfa463028d015e6086a7de0a0889b0780a049ba777ae33a75e8c0c7bd07597d6e6fb43624537a579b9a06b20c89d6918b2980e482000ea07b2632b8b97e159d88f112a8dd9d44df2f3c4502e0c79a29297ea7f61f41f311f851a030590b16841225b9590cdc95b19176201d442ca0b931c6e4314d20a1c772ea9ba052e8f9f247cd159c65b304863d444087f6a60d7dbec3a0e4fa09f007b5a1c64f808080808080808080808080808080f86c9c20120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84df84b0487400e8b4f1c9c00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47022440bac492386862ad3df4b666bc096b0505bb694dab0bec348681af766751cb839576e9c515a09c8bffa30a46296ccc56612490eb480d03bf948e10005bbcc0421f90b3d4e2244295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e9122442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab022443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a224461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252244685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d358224472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a5122447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e22448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d7886948522449bb832254baf4e8b4cc26bd2b52b31389b56e98bab764a39ff81dad720d5691b852898041a3842e09ecbac8025812d51b32223d8420e6ae51a01582220a10f7722de67c12244a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412244b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72244b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002244be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2244cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192244ce2fd7544e0b2cc94692d4a704debef7bcb61328b64abe25614c9cfd32e456b4d521f29c8357f4af4606978296c9be93494072ac05fa86e3d27cc8d66e65000f8ba33fbb2244d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392244e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212244ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c1921832244ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2244ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd02a44295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912a442d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab02a443f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a2a4461dd481a114a2e761c554b641742c973867899d38a80967d39e406a0a9642d41e9007a27fc1150a267d143a9f786cd2b5eecbdcc4036273705225b956d5e2f8f5eb95d252a44685b1ded8013785d6623cc18d214320b6bb647598a60f82a7bcf74b4cb053b9bfe83d0ed02a84ebb10865dfdd8e26e7535c43a1cccd268e860f502216b379dfc9971d3582a4470f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba72a4472b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a512a447ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e2a448b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d788694852a449bb832254baf4e8b4cc26bd2b52b31389b56e98bab764a39ff81dad720d5691b852898041a3842e09ecbac8025812d51b32223d8420e6ae51a01582220a10f7722de67c12a449f8ccdafcc39f3c7d6ebf637c9151673cbc36b888819ec5ec3e97e1f03bbb4bb6055c7a5feac8f4f259df58349a32bb5cb377e2cb1f362b77f1dd398cfd3e9dba46138c32a44a6f79b60359f141df90a0c745125b131caaffd12b772e180fbf38a051c97dabc8aaa0126a233a9e828cdafcc7422c4bb1f4030a56ba364c54103f26bad91508b5220b7412a44b218c5d6af1f979ac42bc68d98a5a0d796c6ab01b659ad0fbd9f515893fdd740b29ba0772dbde9b4635921dd91bd2963a0fc855e31f6338f45b211c4e9dedb7f2eb09de72a44b4dd66d7c2c7e57f628210187192fb89d4b99dd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cd2a44cc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a4192a44d1d6bf74282782b0b3eb1413c901d6ecf02e8e28939e8fb41b682372335be8070199ad3e8621d1743bcac4cc9d8f0f6e10f41e56461385c8eb5daac804fe3f2bca6ce7392a44e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d212a44ee01c3b1283aa067c58eab4709f85e99d46de5fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a44ee226379db83cffc681495730c11fdde79ba4c0cae7bc6faa3f0cc3e6093b633fd7ee4f86970926958d0b7ec80437f936acf212b78f0cd095f4565fff144fd458d233a5b2a44ef0274e31810c9df02f98fafde0f841f4e66a1cd98cbf822e4bc29f1701ac0350a3d042cd0756e9f74822c6481773ceb000641c51b870a996fe0f6a844510b1061f38cd0").to_vec(); let height = 35724800; let trusted_height = 35724799; @@ -492,6 +492,31 @@ mod test { trusted_previous_validator_hash, new_current_validator_hash, new_previous_validator_hash, + 56, + ) + } + + #[test] + fn test_success_update_state_non_neighboring_epoch() { + let header = hex!("0a222f6962632e6c69676874636c69656e74732e7061726c69612e76312e48656164657212d15b0adf0a0adc0af90559a01b8c590cd6b9bcf6c24e47e5f6468083f6093d05f9cc6a3f45c0e61a7989914ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347941284214b9b9c85549ab3d2b972df0deef66ac2c9a03508e22b6e7dd679e544f7badb659cd936e1722f9a91136e800681d588b886aca01aa0294d38be68038c13ca83d122e765b2714e3cf5a7c8b382eab64f009be8eaa026033fa1fdf7e559f128b7380b369d908261c092e97040cd938d0c2cc83c8d52b90100000448000000b680400000c0c00010000280440000920200002040210200009000015e2004022110000830000800100000001222041000004000800040ac100004c0003004102013000540080008820021180000100482004041102000001c00100c68200202009509421005288a684028202400000408912000403080000c000040481c000c80141840181c20001004102084e02800200a040000880c18802006028010c000062808040a2022023082410200880080104a40e00011000000021410981200100a8000026900081200002000808004800420811049ea00206000121002c210000002491000941000110000249000809900084006210020000a00028402620fc884042c1d8083303e3c84663394e3b90337d883010406846765746888676f312e32312e39856c696e7578000000821df8b90808265da01e1a65d62b903c7b34c08cb389bf3d9996f763f030b1adcfb369c5a5df4a18e1529baffe7feaec66db3dbd1bc06810f7f6f88b7be6645418a7e2a2a3f40514c21284214b9b9c85549ab3d2b972df0deef66ac2c98e82934ca974fdcd97f3309de967d3c9c43fa711a8d673af5d75465844bf8969c8d1948d903748ac7b8b1720fa64e50c35552c16704d214347f29fa77f77da6d75d7c752b742ad4855bae330426b823e742da31f816cc83bc16d69a9134be0cfb4a1d17ec34f1b5b32d5c20440b8536b1e88f0f240d3256eb0babe89f0ea54edaa398513136612f5a334b49d766ebe3eb9f6bdc163bd2c19aa7e8cee1667851ae0c1651f01c4cf7cf2cfcf8475bff3e99cab25b05631472d76d76ee8823de52a1a431884c2ca930c5e72bff3803af79641cf964cc001671017f0b680f93b7dde085b24bbc67b2a562a216f903ac878c5477641328172a353f1e493cf7f5f2cf1aec83bf0c74df566a41aa7ed65ea84ea99e3849ef31887c0f880a0feb92f356f58fbd023a82f5311fc87a5883a662e9ebbbefc90bf13aa533c2438a4113804bf980a75ecd1309ea12fa2ed87a8744fbfc9b863d589037a9ace3b590165ea1c0c5ac72bf600b7c88c1e435f41932c1132aae1bfa0bb68e46b96ccb12c3415e4d82af717d8f474cf03cceff28abc65c9cbae594f725c80e12d96c9b86c3400e529bfe184056e257c07940bb664636f689e8d2027c834681f8f878b73445261034e946bb2d901b4b878f8b381fbb860851066357eff502b847239dce4def537c09981995b09a20b0332a5931b6a80a0756929d82d67ada1699558c423a5108b0754fc4a8729fd2967822ee274fecd8742703f1e758c0c25aa65667ac33ca73a09dacf4ffeed749d956d6b438a65fe35f84c8402620fc6a055a683a5f4aec18ad180c783416fa6064fd77d12dd9cce6aa4e2d21814a1358b8402620fc7a01b8c590cd6b9bcf6c24e47e5f6468083f6093d05f9cc6a3f45c0e61a7989914c80ac0efe500470240a4e493ae2a67a28f2974da7a8b00ef170fc1d2357732a713d15528f7773b127095705a9d064c155484a7e3e8ccefefbcd1cacc960b3a0fe5f00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800abe060abb06f90338a00675a9943e5eee827641ecf76ccdca86c00760201e79454d7d70bf1d1229f4e4a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479435552c16704d214347f29fa77f77da6d75d7c752a0f88cae15732bc072d88e3266e79c63ace19f6158d861b5a1527eecea8b3a0c90a0805f0392fd4fe5f40410188ae1823170f330fcbd460029d64100fb762c18db22a068061db6f72b36216ac8a6d4e7ade646d0481a5e58a1d446699f73f0000c65beb901000200000000000008100000400028002100000000101280100000602202000080440850000800001001020001000091010090200a10040008009012000080600042005010001000000010200880020010221000a0000208004a0c88000102140000080061090200800044000000000000080000000008088002090010040200040840000980000008000000000104000000100c200840100000000086001000200400000000008020084009000200204002800000000080008000920c0100000004880a0a0000004001810000000120124000009204080080001040c20000a000000030401000000201004004020001820000c00000000400480008000100a000028402620fc984042c1d80831a1f2484663394e6b90116d883010405846765746888676f312e32312e39856c696e7578000000821df8b9f8b381fbb86091ba1e6cf213db9c2384a8b80d1a61adeca1222451ad44989a3a4353c926cde613198ca3031c6b7c7988b0302c51f2bc1762f889d44c27476f73339069a6aa0b5fce63de2c6e847ee07c01620e47d27d090277ce3069e61a8e0e5dc75e7b6c02f84c8402620fc7a01b8c590cd6b9bcf6c24e47e5f6468083f6093d05f9cc6a3f45c0e61a7989914c8402620fc8a00675a9943e5eee827641ecf76ccdca86c00760201e79454d7d70bf1d1229f4e480899ca0f597006047cc915ce49e35b70eefe652a4f46d2cf8f9954323b29dc13a07ebbdc07dfa4f17138db9af8611fe9a98d289df90b46aacc8d86e6f39c7528e00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800abe060abb06f90338a06f8122b4b7c614859a61d8e12f236efc07d92370c52e9f3f8de48bc4c4c3f76aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479440d3256eb0babe89f0ea54edaa398513136612f5a01d6899d6d2e0f411288f145754d9672ce2881c44d3e9a25a6a33d5f625ec608ca09ef5f809e4322bb7ac0df0c4b4ce82d4fea1e31832734ed2286e1bbf3bcf5967a04f4875ba4450b51981ced70f5cb8ecfcb4f402a2ecca8f038ce9340431ba6677b90100100800080000000008000160000000240000010190000800000040000000008000081421000000100002001101009800001410120000000000001a0000a11200002030300820000200001008002000002010000000000000c000508001101600000800200a02009000010000000148c2080000000004089000080890420000000042000800000000100000011010001001000c200c000200442000801810102f060000000006a02808440000028000040001008800000018000082000000000204414802000089000021400010428000008000840280010100104142000020000010108a08040800118400060000010020208002201000024000100000180000028402620fca840427f164831ba49084663394e9b90116d883010405846765746888676f312e32312e35856c696e7578000000821df8b9f8b381fbb860ae5cfdf126fe914ba373cc010e894bdc02c34c113feaa7bf6e027879725858c3aa8740b6abb90f1dc389003dae1eb30d11aaead3c1df95d86bfe201cf0c5a285dd915f13a712abd523322712c42b8195c6cab1b5b0314375c059f48b8b79c8e4f84c8402620fc8a00675a9943e5eee827641ecf76ccdca86c00760201e79454d7d70bf1d1229f4e48402620fc9a06f8122b4b7c614859a61d8e12f236efc07d92370c52e9f3f8de48bc4c4c3f76a80bf2db108411fe95e684c82f738764633a2d29253d20c1832b7189b7a52f4c7ab75224c2bc89d3d1765b1aea4a347f2526cf24c4518ce3eae863383938cd651a001a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800abe060abb06f90338a0b8f6e83d72a579037a1747385d006303baecd2f9122ea38d7d7caeae4322fafaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479476d76ee8823de52a1a431884c2ca930c5e72bff3a090533b33c3cc5cfecbd33918e04cc12957a3cf6a5844e65a0ca4f2ade2994b3ca0e6977483ef89448a9e5565ceff05271fd57f2ba905f9caad339902e605fc8db8a0465d7a4ebdc6f41f40124db3193e5a0565e6a877854715c5811eb143d1d5f392b9010002801044080080006022024040a0002000a840003012002810184001000409924008152008200011040240012c00100120102002000000200100020000a4702006466030020000000001000c00008000a0180000000000804241102800111710100c46a00a02009500060004288008400c000400081808900001045400020c400240001c0000000000000ab000081008001c0ea028028002042040800810202006480080400006380840100002001402010000c00000000002a08311208022021400981220004881000300c002035001000080808ccc0324001040420000600012383086100002080941c204000411810400800000c020004c08080080480209028402620fcb84042c1954832408c484663394ecb90116d883010405846765746888676f312e32312e39856c696e7578000000821df8b9f8b381fbb860ac51bacb0156bbd71fe9d754817bcd1ef367cd0a6ca2d719fd1f9294164e9ea536937167df9370e7e4271846d099f1c01785e38478fca04f68559d2740447cdfc8f8e1d9bfea1ad6d331b13c63d133504203d7b6197e59837128b91b568c302cf84c8402620fc9a06f8122b4b7c614859a61d8e12f236efc07d92370c52e9f3f8de48bc4c4c3f76a8402620fcaa0b8f6e83d72a579037a1747385d006303baecd2f9122ea38d7d7caeae4322fafa80995177c05ae18a7afb72a5a5b870aa4cec13dd3bec378bd0bdd45c8b32ff9d94379d0649899e58045bd798c90c83f068c6180ac3be527f5264fd1fa40d5f3f7f00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800abe060abb06f90338a0c1828f9fa73b74d490c01682f5e7851683736d6d38437034b118ecd99aac908ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347947f5f2cf1aec83bf0c74df566a41aa7ed65ea84eaa0909eadb50d8d80fed8719a8008f9a96a65105c9f9adf5f09583df44903455d08a07fa76502e2d2fad4544c010c2cb4719b07845b4ade4c57c05c194dbe35f27990a06c6141cf0821319308c5b281ebb93512f27f384d9d039387d765fa27ce7f5ab1b90100020000000004081820000040000000c400000202800200000008400241000080c0001c0000220050000000000200100000000082080000080000100000b064000000201000000011000010080200000020100000240a0400c000000080041700000804200002208000401000085000000a00000000080890000010140000080000400a0800080000000000040082000100000e2018000000000004c208100260060000040000003108081000020000400000004000000000200000200000030004000802001000004000000040101008020000000c06200000584002000020000018000010000000011100040000110280009000008080084400000004090000028402620fcc84042c1d80831f9f5d84663394efb90116d883010405846765746888676f312e32312e39856c696e7578000000821df8b9f8b381fbb860965d6d03c0493b4b7a3cf91fdbe7d114ebd38ce476e1bf47f1d1a55a8286408e61d2fedaac5e6c9b577f808ddeca453619c2fa244c4c8d0c521caf5148b532bcc376df1e5195419b11a350b03b596bbda029f1b074c42a3e9ce26d676c708c3ef84c8402620fcaa0b8f6e83d72a579037a1747385d006303baecd2f9122ea38d7d7caeae4322fafa8402620fcba0c1828f9fa73b74d490c01682f5e7851683736d6d38437034b118ecd99aac908b80e1175bb3858b24abde91024c935edf639b17cd3d48a67110b486064b018cc30273e32fc65969bdfaa4f6c72e0ead81230fa220f767d21f0a434ba82d9d5f6fcd01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800abe060abb06f90338a09c7cfa55ae4789be64a696d357083683dcbc0429843811c125087ffd383311b2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f474cf03cceff28abc65c9cbae594f725c80e12da00e783cf76ba10af8b476c2af6f0099182dc3d8891e6bfe8ccfbd4df4df9e5725a05943a3797fc784ab2a933a7e8cf5502c66932b4d565bf39673d8c84a97e7c163a0887d4fd11bac9b67f2a36358099ecfb8a3777074a31a1b01b0a2ddaa1621e312b9010000010000000080040002824000000024000000001800000000000000002800a0002810400000001004020001084090010094204a010004000000020000a0600002000030000020080800000c8800080020100001000000044200000804405400000802200a02808000040000000008400800000000802000100008100000040001000008000000000000000000a0100000000420080000000008100010100021060000000004842008400800020080040000400840088000000002000000000004102802000088000001200000000020000280040008002000104062004020008010108000000000010040040001010000008000000000004800080008000000018402620fcd84042c1d808310765984663394f2b90116d883010405846765746888676f312e32312e36856c696e7578000000821df8b9f8b381fbb8608ce86edf055073ed3657cb976abaaad5fd17879de455c0261f75a68f1fece6134ccbbad1adb809ce0c8e7b50249422c212357367f0e2feca28deb104d6bbfa1a2dd080a66914b21756e2198cf1c52f50ad6edcc07ec72818f917e9d7111a6574f84c8402620fcba0c1828f9fa73b74d490c01682f5e7851683736d6d38437034b118ecd99aac908b8402620fcca09c7cfa55ae4789be64a696d357083683dcbc0429843811c125087ffd383311b280f18262798880d70059d643979022a2b63e4198d03f7b42b1b2ae3750a00ad54632f0755542d43c630c263fefea44700a9c2f5780aacb850a98fb22816843643701a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800abe060abb06f90338a0fe3e114a9b8862d981e404b7f83f43330e8a6a1d6f853b450ba8f358d8e594aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794980a75ecd1309ea12fa2ed87a8744fbfc9b863d5a020d51c5c97ddeaa92872cb51e57cf30cebf201e4455a7628909a944a153fdd29a08498edb273bef28ea8bfd2cbe9a99e2c94eac71fd9752a46178549e43b3dbb76a0af8c731b24f09013ae128678c593b89c686e5936789049da0a20a421f883e50bb9010012000008000800880000006000001000000000010002808010006006000800a200005c0000220010001800000000110100100102000000000009182000a06000020030380a0000008110000800000000a01000010002020040000000a4001400000880300286009880441010082008600c000000000838910000009008000800004200081000000c000000001000001011000c200a00000a040040c108100020060000040004006808001840020040c000000100000000010000901200c000080404681200100100000000000010000020400000041c000000104002000020001018084010010009011540064008110220009000001000014000980008080000028402620fce84042c1d80831f23d184663394f5b90116d883010405846765746888676f312e32312e39856c696e7578000000821df8b9f8b381f7b8608339e352db1dfd13827e415235e7ad9653cd14056bd7b78e93e09c86c36679ae02e13a2ec4aa1d8e2546fb5655f621d6041c1b9aa04ce18b41b7273fbab06eea3aead2ab3c6bdc791bb6268c781267b4ec81143312f419a48422eab7e7d8f1ebf84c8402620fcca09c7cfa55ae4789be64a696d357083683dcbc0429843811c125087ffd383311b28402620fcda0fe3e114a9b8862d981e404b7f83f43330e8a6a1d6f853b450ba8f358d8e594ae80b25e98a9d4d947ccedfd894f38dae23c09a3f30ea5b513470d75eac608d15b233c39278b14601bcd777c2f0c61fba173b2189614ff7ab761ec48e03ae2894eed00a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42180800abe060abb06f90338a0ad80590a86e436e79aaa961dccc29d85d1304853ded12197ae2dffd42e75fa18a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347941284214b9b9c85549ab3d2b972df0deef66ac2c9a007e946b785a9637930533c6df8d79bb93184e47d65d28f7854d8c8ce16c63c42a015de33fa37a8bafb7578c335909aeff2b2b679997e548ee1a8d9f47a892ab1a7a02ced64c3059d0e81f236cdddfe8d034d05a08e1fe845ba32b4234d5ba8a377d6b901000000200400082008c2000a401000002000200a00103200000000502340000080002c142000000010002300818280140080100002400408000010120000a03000040000108400000000011108020012002210000020020408c80a100000171600020800200e02008001e00001200008001a0001000008089000081014000002040040000800000000000000000102000000000460080000000000088108904866060080800004006008400200060000400080008000900000a000820800020102040008020080000001850008400200004200009004800080111040424800a0000018204a5000020041000015000001020000810000202008440000000000c000018402620fcf84042c1d80831bb60084663394f8b90116d883010406846765746888676f312e32312e39856c696e7578000000821df8b9f8b381f7b8608e8cfe0b055b18d322025f0837aba5e1928a13f666255b83cf0529ed987b9b4e449d6248796bf8a351bf21cbeb4d869b14cfe57601beae23fed96172aaf53b42c247caacd125e363c7d4a36497c20523a72100fc4bc1a8f1db3ef66f882b1b84f84c8402620fcda0fe3e114a9b8862d981e404b7f83f43330e8a6a1d6f853b450ba8f358d8e594ae8402620fcea0ad80590a86e436e79aaa961dccc29d85d1304853ded12197ae2dffd42e75fa18805a390422f87c05ce81fad47bcbabb415c9bec71cdf4d6b8878409322a810d8567ef061cec5384ec4e0a754413ce28e6fdd24f54e84706337e863fef60b2489c100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080120510b89c88131abe1af90d3bf90211a05d54f311542dc86508c3950fe9fd0e42666c4b0d2da357bf0ff5256206c4f499a0de4549196246f89565153fe5c293bd86825c81bebcaf5d863bc20db5b80f39c1a04260cf26a849cc8ae7d9e9490a0f3cae30ddb388a52bbb4381b648c6927f5d02a01043cbea73d2e4dad6a3021744ae80ecceee3fda23997f7e5a56d30721d6a89da0016bc5f3d3af4289603df49b9156999c4b3fab779399bba9dbb8d98a7d5fff36a09f7ae1ed754c036e23f8cee8168086eb854e9a74e50f80fe6eeedc06652d65a4a0aa0c44232305f2d9c73f4198c114a79f935d4f15479dcd8d61ab3fe5821608c3a0b2afddeb92bff5ff52f0d7d432e3b5e2c777988181eef046d4026e23a28a15fba02a6282e9d54cbe11efd2a4a36c899aeaa7cf7604c6c1d496d4ec36b26870d945a0d7c965d118cacf4d7282ee52216d42b231163efbb82fafc36bf6dccc2ace3b53a0e05dadba137f39580b713d54564bb2ccb48a4a4e882ac673aa972f6b4a7e2c84a0e35f8dffad08d4c9df98129ee14a657c0076c7e5ed00fea40d7bf4f9ae07c2c4a04a9dc6bc9c6a276620ccc29879f3e4195951f720322b72f3925c5862c5972487a06a7b7c9de98a1f4d36cf112f45b71e797694ed5b0c8ffcdcea26ed337bcea62ca0904b2f7a0c508f1876c1ffbba7832ef5babe8218fb7ac12d0f9bf4245b356a39a0bc5622b08b6882c64c3fd5ca4feb7cbe7845c911b3518874784719dac87bf31380f90211a0ed46c5f969903bd014b453e23bf036a0807d974ac245d974bea3edbfab8998f7a0fbe185c3ad730c361d61adafbf283c230a9e04a6971a5693a58b95d54a91dc18a01c49f9acbb2ef6407d5d88ad62c7e41c0ae4e1a86453d107f8b88e366e6f1f27a07f263e0e9ae17cbc40f87c3ce1249a552a18c5dc0b7fe42e43454663ac9d4a10a0ef16b26fa26244501acfcc480235d9fd3859b0511b1d840cb3960143eac49e4ea05e19c98be009508b8132d6bc03ce932ae80c584fed6c8b66690f51b6706c6110a02699c04fa558d4cf31a72eccdbd6c9b85921b18e92be8013b16bbbb0e0243d95a0bf06ce588155b0a5b8dd34eeb8b34d1ab6698da02bbd47b8df956f3f8f958f51a0105ad803a3be71de2802142849753f93fe3445762ccdccda5baafb2c350fe8ffa06e725a7130ddbff26e37c27c25830b6c3fac3575371cd00d26e799c30cfc61e5a045a5861fe345d073abd640549c0bc754f98a15f1349dc94ccaf8e366d747e800a01fa1a61b7b9716a711f42192e558ba2fcf059d8b87ad67cb4c73aa65bc918226a0e3b653f8469bce44931ae9a2f88c3ae385b70bae52b43902b618a0e29694dd8ca09f207e2e88901b54fb464545a33764841152a2669f6668610bc3fa10d5cfc2bba00393790748f68bcffb6f9e01a409b9d1e691406b635a1cca73ae061813ac4d5ba0c3f4178174074d467324173d8436674ce6c69fa7c49a4337a000635fb04dbf2380f90211a079c04022f20db8c5fcf561e1956bfe73e94c6e4cb2655ff506c2e298f1ab8f4da0c0c9908e024252617bb968a090881f478cf2cedee6762524d4b2d3521fce7b30a09a502add7d10c7817db9157721c4b03ff3327415d6d3b0307b11efa07a2ca300a0911e146a2367ecc6ea7dd6c2547ac9df60ead03cd1d14ddb3350b3968c7fca53a05cd154e740f91a9fc1b2b780c47cc5f525efab2e7c7c36248a2833a99206f291a03761f080edb655d24c234da08813efc750a093ea75e9603d558dd2889e254363a0035ad7eda8fb804cc3b2779b0f3c40e67f5c7fef6b354878cc659bb76c02871ea089848d6e6e0132be50e1428656da8fadda12cb411681a9cab7d5d9371650f2e3a054ab857606b93e77c264d3ae1c75bb7d8e532a75823fa0646934c6b07587d97da04303a53d5b1cf36d7ca5b3a35ff11b210b7fab8f2bea560fee8e1dc49863af08a083b73ad7bf82dc689745a5bd39837939169c725f44b3bbe5c2b9470c557cb6c1a01eb14803b41ee30b3d9256decc6b02f7b4eac0cba1cf60c7e806aa145dc95c3fa00f46a8879a158446fd5281f67942859516c094afff5c862d7925e28e0255dc1aa0a88775f84e8812564ca66ffdfc617993b642e48863299520f34c9e4f2b394b24a065a8676f56698d3c88c8360411a1b5d89cbdf44cef98a51fe1b761ed82177bdda0e9216b548ea5ad232ccea4285597ba3345a53d39fcd61de9546c24725edac4c980f90211a0fd00080f96539f8eb5a2b403c9594f7bbf1a9a773c9a4430d86ee7f4fc67f041a083d0f27ec441ee36c6b0479c30d213d373edacc372fc3818fc98eac3c53da4d9a09eefca974fe868babfc32bf6e1449d97d14a891e3b10bbe54f64e00a0b5dcca1a0ad7b3367ca39009b957a1825269c78ca3af9a2a87c43894fb8bb9ec165d7a4bea07b68db0a8ff70d3557ae4c04b964de0fb67e3c340f3649c0af4bf79b86e73be1a02af8fdf09ff77e7f4d0e325050a8f293c08d2cb328f8d3da7e083a7d48924224a032a90f4a4456c9a1cefc92ea7026d74d9c1c5117e8b7d405e9d9440a8edfefbba03c40b1884e0810d2d3579d8be5483a651ae4ea3041f484ddef2f0ad5a70efc06a06c34468de46e1c6fd59005d0201b3de36cab1a04daf1b42073e91fe35cac978ea05901b53bc10fe26bfa1936e1ba5a334d168558454429aecd803d3e63304984dda08e3a481bb8b089125b4e820bc9e59c606c47631394830b9b37c06c77110bc512a06411f9d1b96b36d413236b20ecaa77fef4bf17c023b6a0feb143a7dfd529053da0c388a4b630d106f22778df9782863b29cc712d25423c704117a9cd46190d55a6a0c3260e27d68de22e8dd36e2a15055e3f9cc0a1503510f8352be2458ce2849cf8a000d1dc7f94ab884d393c18ad9816d364c001e8ed29b5339d7d673d05d8cf8c18a0cc90581b3014a0af5d5a263a6581f442d75cccfce15f6da447c30aa3eee35adc80f90211a0f4f253a2981255c3c0c2b023a074cf35ee982c4709fe56d3cfbcc0d2d3e9e060a0c97e5c55396e530fb20bab042aabdf2883db66f41abb6c71f8eefdae67334800a006d2ac360ebe8eb14a59e2cccd35c3a23d9c559f183102ebdb3db068fdf6a634a03a78bec1492adf068ece5e9820d72df85d2e0b2b992f0cacb7198fc956473d94a0eecba4d8055f6358c4ed0989fbf575de5f137c4ffc73a53ade1d708c45641131a0eee901dcdf7b3b76f230c684200e990fc2284b3a3cac8156795643a8bf45f543a0c679d68e57dd545e7489f10898128a6a90ad7df29d3380ea3fa2c8d036a714c3a063062d6a6c1cfe1efff0e6965a65446b61982e763eb36652e1423df1fad08643a0d6c8ae23af8ad991e84c43f69bf280c54fc3a731b210bd60f5b8f39043480017a04614a62c039ff880d7c65c891e6fc6c55bf81bddadb42b5171a8d07f7218d7c2a0bfec07e9660db8afc02cd6cc2524246febc098f596a717190d1ef155317ce046a02aec38d6659b1b72f03b7b80e078dbc40650cea494f56606154538491df2598ea0c75fdcc0ec88840ac16c38f4a5902dc1e87d704cfdcec825b0aeee25fac08c32a0e09b0acd86da73ca9edd0ed45f52e970c710860aced6d2e1bb3617d45d1f1cc2a0bd67f755acb481bd586d2adae80b8155e8c887452ff964c8dd0ac888032b7d1ca04f03b5b8ef01c49629b79e51438d92a2dd9a490508152a96787ea1c39e1358e180f901b1a0b253f4d804466eedf2500f7c56b7b5c81937fd8547fbe942756bf1c2974245b9a0dfb6b4a54ee26fb0acc8a98e28efc6a9bef48610921ed4c5ddad4a6770ec413780a0e5b8323277c3cd8b0da5297fc709533d25bc28964698a6f2cbc4ba80c4c474c880a0ad4e25adf77388513a19b6e66f340845f4da575e05cbb41ec3ccacc962beb934a0ec3b2876d5a7b8fb4c959b2e2efd9a3fee75ee4e65da5438010367610ca50ccca0316db872ded9164c79a846190e57eb2c3a4379087798b8e1220b3cc5ff5aea06a05ad6bcb5a22ccc01a7b218c06c217b5c6f6a54cd77dbf3385422f37c3a5bbdc4a039d08aa5ea4684c934cd1911177ebea1f2f3438d891da946a0396ac10b663b1ea0c73d499a0e4709723af701832cc2e07949df500d5a817709746c124757f2a46d80a07967cd6ca41b76eceb64c5373d85399a380af1d1eae78f56a33a149677398df3a0753f05888f5454aba005e67e1061a0bbb982c308cf90a89746abebc76f640d44a01eba4f5159fcb36c5bde7933e2632b0923167fad080618e90b90e98f450e0673a0dc9282be875f1e21a4245c23816f7c36bfaee11d34c472c29ae4576985f2e9e880f8b180a0f53d8c2cc17264e3f43339e6390b3de4123e0d3014e2437d51e9527d32531dbba00cbb4e2b6e1f2b59fb98c96cd2ee4a0a9994e91d18564b8289c5dbf42d653e6a80a0585dc8b79c33d7f248c845ac6c35ea102dc2fd2870e4e96ae7891ea6093b3e6880808080808080a05b8b9aed0df2c69df192889f2a5c791f16590efae13338ab7279ea1bab2fd0b38080a07308e7b9a6597a64d45bafaf4b3a2a4525895d77c7d8c146ef7720f5c693f7b180f86e9d30e1120c458c4c09a9448628f84e81161b308d5c4041a3d3a1ea329d0eb84ef84c588823d85d5096750e00a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470224408265da01e1a65d62b903c7b34c08cb389bf3d9996f763f030b1adcfb369c5a5df4a18e1529baffe7feaec66db3dbd1bc06810f7f6f88b7be6645418a7e2a2a3f40514c222441284214b9b9c85549ab3d2b972df0deef66ac2c98e82934ca974fdcd97f3309de967d3c9c43fa711a8d673af5d75465844bf8969c8d1948d903748ac7b8b1720fa64e50c224440d3256eb0babe89f0ea54edaa398513136612f5a334b49d766ebe3eb9f6bdc163bd2c19aa7e8cee1667851ae0c1651f01c4cf7cf2cfcf8475bff3e99cab25b05631472d224476d76ee8823de52a1a431884c2ca930c5e72bff3803af79641cf964cc001671017f0b680f93b7dde085b24bbc67b2a562a216f903ac878c5477641328172a353f1e493cf22447f5f2cf1aec83bf0c74df566a41aa7ed65ea84ea99e3849ef31887c0f880a0feb92f356f58fbd023a82f5311fc87a5883a662e9ebbbefc90bf13aa533c2438a4113804bf2244980a75ecd1309ea12fa2ed87a8744fbfc9b863d589037a9ace3b590165ea1c0c5ac72bf600b7c88c1e435f41932c1132aae1bfa0bb68e46b96ccb12c3415e4d82af717d82244b71b214cb885500844365e95cd9942c7276e7fd8a2750ec6dded3dcdc2f351782310b0eadc077db59abca0f0cd26776e2e7acb9f3bce40b1fa5221fd1561226c6263cc5f2244f474cf03cceff28abc65c9cbae594f725c80e12d96c9b86c3400e529bfe184056e257c07940bb664636f689e8d2027c834681f8f878b73445261034e946bb2d901b4b8782a441284214b9b9c85549ab3d2b972df0deef66ac2c98e82934ca974fdcd97f3309de967d3c9c43fa711a8d673af5d75465844bf8969c8d1948d903748ac7b8b1720fa64e50c2a4435552c16704d214347f29fa77f77da6d75d7c752b742ad4855bae330426b823e742da31f816cc83bc16d69a9134be0cfb4a1d17ec34f1b5b32d5c20440b8536b1e88f0f22a4440d3256eb0babe89f0ea54edaa398513136612f5a334b49d766ebe3eb9f6bdc163bd2c19aa7e8cee1667851ae0c1651f01c4cf7cf2cfcf8475bff3e99cab25b05631472d2a4476d76ee8823de52a1a431884c2ca930c5e72bff3803af79641cf964cc001671017f0b680f93b7dde085b24bbc67b2a562a216f903ac878c5477641328172a353f1e493cf2a447f5f2cf1aec83bf0c74df566a41aa7ed65ea84ea99e3849ef31887c0f880a0feb92f356f58fbd023a82f5311fc87a5883a662e9ebbbefc90bf13aa533c2438a4113804bf2a44980a75ecd1309ea12fa2ed87a8744fbfc9b863d589037a9ace3b590165ea1c0c5ac72bf600b7c88c1e435f41932c1132aae1bfa0bb68e46b96ccb12c3415e4d82af717d82a44b71b214cb885500844365e95cd9942c7276e7fd8a2750ec6dded3dcdc2f351782310b0eadc077db59abca0f0cd26776e2e7acb9f3bce40b1fa5221fd1561226c6263cc5f2a44f474cf03cceff28abc65c9cbae594f725c80e12d96c9b86c3400e529bfe184056e257c07940bb664636f689e8d2027c834681f8f878b73445261034e946bb2d901b4b878").to_vec(); + let height = 39981000; + let trusted_height = 39980600; + let trusted_current_validator_hash = + hex!("674c4f3d0b24204759cd9b4d9a641bdeed6adff81bafe9965451045916b6b4de"); + let trusted_previous_validator_hash = + hex!("efa11eef8adc20d6f179dff684c16891761d632462147830cb45579589632786"); + let new_current_validator_hash = + hex!("8a4bca6491ec89e201ea0e2776f0ae42f7e5c8d67a305a7aa6284a0e0150f736"); + let new_previous_validator_hash = trusted_previous_validator_hash; + do_test_success_update_state( + header, + height, + trusted_height, + trusted_current_validator_hash, + trusted_previous_validator_hash, + new_current_validator_hash, + new_previous_validator_hash, + 97, ) } @@ -514,6 +539,7 @@ mod test { trusted_previous_validator_hash, new_current_validator_hash, new_previous_validator_hash, + 56, ) } @@ -526,6 +552,7 @@ mod test { trusted_previous_validator_hash: Hash, new_current_validator_hash: Hash, new_previous_validator_hash: Hash, + chain_id: u64, ) { let any: Any = header.try_into().unwrap(); let header = Header::try_from(any.clone()).unwrap(); @@ -540,7 +567,7 @@ mod test { }; mock_consensus_state.insert(Height::new(0, trusted_height), trusted_cs.clone()); let cs = ClientState { - chain_id: ChainId::new(56), + chain_id: ChainId::new(chain_id), ibc_store_address: hex!("151f3951FA218cac426edFe078fA9e5C6dceA500"), latest_height: Height::new(0, height), ..Default::default() @@ -819,8 +846,11 @@ mod test { let misbehavior = Misbehaviour::try_from(any.clone()).unwrap(); let mut mock_consensus_state = BTreeMap::new(); let trusted_cs = ConsensusState { - current_validators_hash: misbehavior.header_1.current_validators_hash(), - previous_validators_hash: misbehavior.header_1.previous_validators_hash(), + current_validators_hash: misbehavior + .header_1 + .current_epoch_validators_hash() + .unwrap(), + previous_validators_hash: misbehavior.header_1.previous_epoch_validators_hash(), ..Default::default() }; mock_consensus_state.insert(misbehavior.header_1.trusted_height(), trusted_cs); diff --git a/light-client/src/client_state.rs b/light-client/src/client_state.rs index 661c5e0..096f010 100644 --- a/light-client/src/client_state.rs +++ b/light-client/src/client_state.rs @@ -77,8 +77,8 @@ impl ClientState { .try_into() .map_err(Error::UnexpectedStorageRoot)?, timestamp: header.timestamp()?, - current_validators_hash: header.current_validators_hash(), - previous_validators_hash: header.previous_validators_hash(), + current_validators_hash: header.current_epoch_validators_hash()?, + previous_validators_hash: header.previous_epoch_validators_hash(), }; Ok((new_client_state, new_consensus_state)) diff --git a/light-client/src/errors.rs b/light-client/src/errors.rs index c9ee95d..895f97b 100644 --- a/light-client/src/errors.rs +++ b/light-client/src/errors.rs @@ -50,8 +50,8 @@ pub enum Error { UnexpectedValidatorsHashSize(Vec), // Header error - MissingPreviousTrustedValidators(BlockNumber), - MissingCurrentTrustedValidators(BlockNumber), + MissingPreviousValidators(BlockNumber), + MissingCurrentValidators(BlockNumber), OutOfTrustingPeriod(Time, Time), HeaderFromFuture(Time, core::time::Duration, Time), MissingTrustedHeight, @@ -254,11 +254,11 @@ impl core::fmt::Display for Error { Error::MissingValidatorInEpochBlock(e1) => { write!(f, "MissingValidatorInEpochBlock : {:?}", e1) } - Error::MissingPreviousTrustedValidators(e1) => { - write!(f, "MissingPreviousTrustedValidators : {:?}", e1) + Error::MissingPreviousValidators(e1) => { + write!(f, "MissingPreviousValidators : {:?}", e1) } - Error::MissingCurrentTrustedValidators(e1) => { - write!(f, "MissingCurrentTrustedValidators : {:?}", e1) + Error::MissingCurrentValidators(e1) => { + write!(f, "MissingCurrentValidators : {:?}", e1) } Error::UnexpectedMixHash(e1) => { write!(f, "UnexpectedMixHash : {:?}", e1) diff --git a/light-client/src/header/mod.rs b/light-client/src/header/mod.rs index b45fafe..65d9fc0 100644 --- a/light-client/src/header/mod.rs +++ b/light-client/src/header/mod.rs @@ -35,6 +35,10 @@ pub struct Header { headers: ETHHeaders, trusted_height: Height, previous_validators: ValidatorSet, + /// validator set + /// - not a epoch block: current epoch validators (which must be in trusted cons state) + /// - non neighboring epoch header: validators in trusted cons state + /// - neighboring epoch header: validators in extra data current_validators: ValidatorSet, } @@ -62,12 +66,17 @@ impl Header { &self.headers.target.root } - pub fn previous_validators_hash(&self) -> Hash { + pub fn previous_epoch_validators_hash(&self) -> Hash { self.previous_validators.hash } - pub fn current_validators_hash(&self) -> Hash { - self.current_validators.hash + /// In non-adjacent epochs, current_validators contains the validator set of trusted_height, + /// so you need to use the validator set of extra_data of target. + pub fn current_epoch_validators_hash(&self) -> Result { + if self.headers.target.is_epoch() { + return Ok(self.headers.target.get_validator_set()?.hash); + } + Ok(self.current_validators.hash) } pub fn block_hash(&self) -> &Hash { @@ -81,11 +90,13 @@ impl Header { ) -> Result<(), Error> { if self.is_non_neighboring_epoch() { let n_val = self.headers.target.get_validator_set()?; + // 'current_validators' are trusted validators in non-neighboring epoch verification. + let t_val = &self.current_validators; let (t_val, n_val) = verify_validator_set_non_neighboring_epoch( consensus_state, self.height(), self.trusted_height(), - &self.current_validators, + t_val, &n_val, )?; @@ -242,19 +253,11 @@ impl TryFrom for Header { } if value.previous_validators.is_empty() { - return Err(Error::MissingPreviousTrustedValidators( - headers.target.number, - )); + return Err(Error::MissingPreviousValidators(headers.target.number)); } - // Epoch header contains validator set - // - not a epoch block: current epoch validators (which must be in trusted cons state) - // - non neighboring epoch header: validators in trusted cons state - // - neighboring epoch header: validators in extra data if value.current_validators.is_empty() { - return Err(Error::MissingCurrentTrustedValidators( - headers.target.number, - )); + return Err(Error::MissingCurrentValidators(headers.target.number)); } Ok(Self { @@ -368,7 +371,7 @@ pub(crate) mod test { }; let err = Header::try_from(raw).unwrap_err(); match err { - Error::MissingPreviousTrustedValidators(number) => { + Error::MissingPreviousValidators(number) => { assert_eq!(number, h.number); } err => unreachable!("{:?}", err), @@ -391,7 +394,7 @@ pub(crate) mod test { }; let err = Header::try_from(raw).unwrap_err(); match err { - Error::MissingCurrentTrustedValidators(number) => { + Error::MissingCurrentValidators(number) => { assert_eq!(number, h.number); } err => unreachable!("{:?}", err),