diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c1248f09..f34f4bba 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -129,14 +129,18 @@ jobs: rustup default ${{ matrix.rust }} rustup target add wasm32-unknown-unknown - name: Install DFX + env: + DFXVM_INIT_YES: true run: | - wget --output-document install-dfx.sh "https://internetcomputer.org/install.sh" - bash install-dfx.sh < <(yes Y) + wget --output-document install-dfx.sh "https://sdk.dfinity.org/install.sh" + bash install-dfx.sh rm install-dfx.sh + source "$HOME/.local/share/dfx/env" dfx cache install echo "$HOME/bin" >> $GITHUB_PATH - name: Run e2e tests run: | + source "$HOME/.local/share/dfx/env" ./scripts/e2e-tests # Lints all of the shell scripts. diff --git a/Dockerfile b/Dockerfile index e2623d7b..be1ad0ab 100644 --- a/Dockerfile +++ b/Dockerfile @@ -59,7 +59,9 @@ RUN mkdir -p src/xrc-tests/src && \ # Install dfx COPY dfx.json dfx.json -RUN DFX_VERSION="$(jq -cr .dfx dfx.json)" sh -ci "$(curl -fsSL https://sdk.dfinity.org/install.sh)" + +ENV PATH="/root/.local/share/dfx/bin:${PATH}" +RUN DFXVM_INIT_YES=true DFX_VERSION="$(jq -cr .dfx dfx.json)" sh -c "$(curl -fsSL https://sdk.dfinity.org/install.sh)" && dfx --version # Start the second container FROM builder AS build diff --git a/src/xrc-tests/docker/base.Dockerfile b/src/xrc-tests/docker/base.Dockerfile index a57ab060..0b96d6ec 100644 --- a/src/xrc-tests/docker/base.Dockerfile +++ b/src/xrc-tests/docker/base.Dockerfile @@ -25,7 +25,9 @@ RUN apt-get update && apt-get install -y \ WORKDIR /work ADD /src/xrc/xrc.did /work/src/xrc/xrc.did ADD /dfx.json /work/dfx.json -RUN DFX_VERSION="$(jq -cr .dfx dfx.json)" sh -ci "$(curl -fsSL https://sdk.dfinity.org/install.sh)" + +ENV PATH="/root/.local/share/dfx/bin:${PATH}" +RUN DFXVM_INIT_YES=true DFX_VERSION="$(jq -cr .dfx dfx.json)" sh -c "$(curl -fsSL https://sdk.dfinity.org/install.sh)" && dfx --version # Make a default identity RUN dfx identity get-principal diff --git a/src/xrc-tests/src/mock_responses/forex.rs b/src/xrc-tests/src/mock_responses/forex.rs index a0a96bed..42d359e4 100644 --- a/src/xrc-tests/src/mock_responses/forex.rs +++ b/src/xrc-tests/src/mock_responses/forex.rs @@ -13,6 +13,7 @@ mod italy; mod myanmar; mod nepal; mod switzerland; +mod turkey; mod uzbekistan; pub fn build_common_responses( @@ -63,6 +64,9 @@ where Forex::SwissFederalOfficeForCustoms(_) => { switzerland::build_response_body(yesterday_timestamp, rates) } + Forex::CentralBankOfTurkey(_) => { + turkey::build_response_body(yesterday_timestamp, rates) + } }) .unwrap_or_default(); ExchangeResponse::builder() diff --git a/src/xrc-tests/src/mock_responses/forex/turkey.rs b/src/xrc-tests/src/mock_responses/forex/turkey.rs new file mode 100644 index 00000000..c3849f3e --- /dev/null +++ b/src/xrc-tests/src/mock_responses/forex/turkey.rs @@ -0,0 +1,101 @@ +use std::collections::HashMap; + +use crate::container::ResponseBody; + +const TEMPLATE: &str = r#" + + + + 1 + ABD DOLARI + US DOLLAR + [USD_BUY] + [USD_SELL] + 30.2740 + 30.3953 + + + + + 1 + AVUSTRALYA DOLARI + AUSTRALIAN DOLLAR + [AUD_BUY] + [AUD_SELL] + 19.7866 + 20.1277 + 1.5205 + + + + 1 + ÇİN YUANI + CHINESE RENMINBI + [CNY_BUY] + [CNY_SELL] + + + 7.1788 + + + + 1 + EURO + EURO + [EUR_BUY] + [EUR_SELL] + 32.7655 + 32.8968 + + 1.0823 + + + 1 + İNGİLİZ STERLİNİ + POUND STERLING + [GBP_BUY] + [GBP_SELL] + 38.3130 + 38.5975 + + 1.2677 + + + 100 + JAPON YENİ + JAPENESE YEN + [JPY_BUY] + [JPY_SELL] + 20.3812 + 20.6706 + 147.74 + + + +"#; + +pub fn build_response_body(timestamp: u64, rates: HashMap<&str, &str>) -> ResponseBody { + let date = time::OffsetDateTime::from_unix_timestamp(timestamp as i64).expect( + "Failed to make date from given timestamp while build response for the Central Bank of Turkey.", + ); + let format = time::format_description::parse("[day].[month].[year]") + .expect("Unable to determine time format for the Central Bank of Turkey."); + let date_string = date + .format(&format) + .expect("Failed to format date for the Central Bank of Turkey."); + let xml = TEMPLATE + .replace("[DATE_STRING]", &date_string) + .replace("[EUR_BUY]", rates.get("EUR").cloned().unwrap_or("32.7884")) + .replace("[EUR_SELL]", rates.get("EUR").cloned().unwrap_or("32.8475")) + .replace("[GBP_BUY]", rates.get("GBP").cloned().unwrap_or("38.3398")) + .replace("[GBP_SELL]", rates.get("GBP").cloned().unwrap_or("38.5397")) + .replace("[USD_BUY]", rates.get("USD").cloned().unwrap_or("30.2952")) + .replace("[USD_SELL]", rates.get("USD").cloned().unwrap_or("30.3497")) + .replace("[JPY_BUY]", rates.get("JPY").cloned().unwrap_or("20.4569")) + .replace("[JPY_SELL]", rates.get("JPY").cloned().unwrap_or("20.5924")) + .replace("[CNY_BUY]", rates.get("CNY").cloned().unwrap_or("4.3914")) + .replace("[CNY_SELL]", rates.get("CNY").cloned().unwrap_or("4.4129")) + .replace("[AUD_BUY]", rates.get("AUD").cloned().unwrap_or("19.8780")) + .replace("[AUD_SELL]", rates.get("AUD").cloned().unwrap_or("20.0076")); + ResponseBody::Xml(xml.as_bytes().to_vec()) +} diff --git a/src/xrc-tests/src/tests/basic_exchange_rates.rs b/src/xrc-tests/src/tests/basic_exchange_rates.rs index 36115b77..5733d3cb 100644 --- a/src/xrc-tests/src/tests/basic_exchange_rates.rs +++ b/src/xrc-tests/src/tests/basic_exchange_rates.rs @@ -66,68 +66,74 @@ use crate::{ /// 5. The XRC divides the BTC/USD by the forex rate EUR/USD. The division works by inverting EUR/USD to USD/EUR then multiplying /// USD/EUR and BTC/USD resulting in BTC/EUR. /// a. This results in the following rates: -/// [38422830017, 38451184548, 38451667997, 38486929114, 38490976280, 38499044560, 38509976251, 38515330948, 38515815203, 38539153477, -/// 38555189062, 38563270803, 38574220730, 38603446631, 38654871669, 38719357870, 38834475422, 38863133731, 38863622360, 38899261248, -/// 38903351774, 38911506495, 38922555303, 38927967367, 38928456811, 38952045120, 38968252504, 38976420829, 38987488069, 39017027083, -/// 39045506957, 39069003067, 39074321000, 39074812283, 39114757593, 39122956627, 39134065476, 39134180145, 39163715544, 39281309055, -/// 39463823450, 39492946194, 39493442741, 39533816007, 39542102882, 39553330746, 39583298473, 39611164966, 39640396442, 39640894843, -/// 39677246509, 39681418846, 39689736660, 39701006445, 39702151829, 39706526750, 39707025983, 39731086058, 39747617590, 39755949281, -/// 39767237866, 39797367660, 39850383164, 39916863784, 40011277739, 40011277739, 40040804482, 40040804482, 40041307917, 40041307917, -/// 40078026772, 40078026772, 40082241254, 40082241254, 40090643087, 40090643087, 40102026707, 40102026707, 40107602774, 40107602774, -/// 40108107049, 40108107049, 40132410155, 40132410155, 40149108672, 40149108672, 40157524522, 40157524522, 40168927134, 40168927134, -/// 40199361269, 40199361269, 40252912282, 40252912282, 40253099956, 40282805154, 40283311632, 40290860837, 40320064424, 40320064424, -/// 40320593902, 40321100855, 40324492364, 40332944976, 40344397398, 40362320218, 40370780759, 40374964479, 40382243924, 40412839680, -/// 40496194902, 40519786183, 40534183828, 40549688186, 40550198019, 40591651582, 40600160195, 40611688492, 40642458087, 40659696920, -/// 40659696920, 40689702172, 40689702172, 40690213765, 40690213765, 40722519509, 40731810464, 40731810464, 40740348456, 40740348456, -/// 40751916559, 40751916559, 40752571121, 40753083505, 40764491691, 40782792398, 40782792398, 40794744473, 40803295658, 40814881634, -/// 40845805179, 40905247372, 40905247372, 40953897461, 40968449356, 40984119820, 40984635116, 41026532794, 41035132565, 41046784371, -/// 41053640089, 41077883618, 41083936055, 41084452605, 41126452325, 41135073040, 41142463123, 41146753224, 41172824637, 41173342305, -/// 41177928213, 41201224636, 41215432895, 41224072262, 41235777716, 41267020155, 41301569626, 41390929077, 41493470843, 41524091387, -/// 41524613471, 41536969936, 41567063158, 41567622580, 41568145212, 41575776231, 41583245489, 41587581551, 41610639400, 41613932283, -/// 41614455497, 41619090535, 41619361608, 41631179304, 41656997027, 41662721320, 41665728952, 41677559814, 41684965139, 41695963084, -/// 41709136970, 41726733058, 41727257691, 41744056589, 41754506310, 41765522603, 41769914536, 41772975447, 41778670130, 41787818380, -/// 41790533061, 41796343910, 41796869418, 41803802253, 41804327855, 41822195812, 41834373399, 41839597425, 41847063487, 41848367626, -/// 41855835253, 41860250348, 41867720095, 41891965920, 41899441327, 41947771713, 41956535284, 41956535284, 41987497551, 41987497551, -/// 41988025462, 41988025462, 42017751313, 42025249166, 42030948884, 42030948884, 42039759195, 42039759195, 42051696262, 42051696262, -/// 42083556884, 42083556884, 42131559633, 42142409033, 42173508467, 42174038717, 42194924689, 42194924689, 42201845839, 42209917551, -/// 42209917551, 42214749442, 42217152297, 42226001639, 42226062877, 42226062877, 42226593788, 42226593788, 42237991588, 42245902261, -/// 42246433421, 42269761093, 42269761093, 42269993358, 42278621463, 42278621463, 42289621008, 42290626354, 42290626354, 42298485541, -/// 42310496072, 42322668002, 42322668002, 42323340298, 42342552775, 42354573252, 42355105779, 42360507948, 42371684125, 42396913821, -/// 42398404459, 42402952755, 42403485890, 42407291794, 42414910436, 42419333221, 42446210966, 42446744644, 42446834028, 42449746627, -/// 42449746627, 42451472384, 42455731515, 42467786695, 42469691106, 42490137005, 42499043569, 42499962570, 42511111048, 42543319747, -/// 42578937759, 42593904382, 42625337002, 42625872933, 42627573542, 42667019815, 42669448412, 42671060904, 42678392562, 42690510967, -/// 42698506391, 42699043241, 42722855590, 42742693521, 42750848781, 42750848781, 42751653025, 42763792232, 42782397220, 42782397220, -/// 42782935126, 42782935126, 42796192376, 42814339913, 42826671166, 42826671166, 42835648272, 42835648272, 42843343871, 42843343871, -/// 42847811330, 42847811330, 42851135823, 42874960567, 42874960567, 42875499636, 42875499636, 42880275131, 42880275131, 42919330304, -/// 42919330304, 42924692812, 42928326833, 42928326833, 42940516205, 42940516205, 42973050245, 42973050245, 42974190865, 43009028035, -/// 43009028035, 43045882794, 43102081717, 43102081717, 43408273596, 43408273596, 43445782508, 43477843781, 43478390430, 43480689686, -/// 43480689686, 43520360250, 43522837419, 43531960452, 43544321225, 43552476558, 43553024145, 43577312740, 43597547431, 43606686124, -/// 43619068115, 43652116263, 43670626751, 43708158579, 43711593568, 43723126209, 43755392150, 43755942289, 43783186707, 43800673013, -/// 43809854284, 43822293964, 43855496086, 43884628792, 43884628792, 43917013915, 43917013915, 43917566086, 43917566086, 43959954895, -/// 43959959844, 43959959844, 43962462035, 43962462035, 43971553062, 43971677220, 43971677220, 43984162849, 43984162849, 43987177202, -/// 43992400559, 43992400559, 43992953678, 43992953678, 44004002332, 44004555597, 44017487612, 44017487612, 44037926693, 44037926693, -/// 44047157697, 44047157697, 44049540473, 44058773910, 44059664758, 44059664758, 44071284270, 44093046725, 44093046725, 44104675041, -/// 44111744188, 44111744188, 44149655125, 44149655125, 44179900474, 44225441114, 44225441114, 44237104345, 44347570567, 44421553645, -/// 44430922636, 44539133510, 44550884484, 44583761278, 44584321832, 44629899390, 44635497705, 44639254480, 44647274103, 44651929665, -/// 44680222029, 44680783796, 44685760364, 44726459965, 44735835295, 44748537904, 44782441799, 44819934443, 44822691052, 44897466753, -/// 44916906174, 45016306316, 45063498524, 45066263322, 45113702916, 45235990342, 45311455532, 45319541129, 45518685373, 45518685373, -/// 45549083567, 45719144915, 45720339981, 45732402599, 45766151306, 45766726727, 45777314266, 45777314266, 45795416129, 45798822161, -/// 45810905485, 45813513031, 45823116224, 45836127564, 45844712124, 45845288532, 45870855474, 45892155149, 45901774826, 45914808501, -/// 45916632484, 45949596024, 45969080748, 46008587936, 46015977015, 46087564913, 46180954454, 46180954454, 46210167718, 46257996085, -/// 46257996085, 46289490721, 46380436848, 46380436848, 46460065280, 46480784859, 46480784859, 46503648831, 46767874109, 46929358864, -/// 46929358864, 47001868597, 47134371115, 47215280578, 47268924669, 47384047456, 47435261561, 47486566863, 47610475869, 47610475869, -/// 47692202599, 47692202599, 47704780092, 47891699427, 47941906012, 47995317184, 48125415655, 48205701144, 48214303205, 48333297308, -/// 48426167684, 48426167684, 48437870498, 48640702875, 48701316363, 48701316363, 48724198063, 48849533459, 48905331829, 48955223570, -/// 49161818104, 49246207822, 49342963085, 49342963085, 49449720773, 49449720773, 49615127444, 49700295300, 50145054511, 50231132024, -/// 50465164177, 50651570207, 50651570207, 50738517190, 50738517190, 50751898064, 51420561489, 51531814238, 52784267858, 52874875766] +/// [37606252139, 37668988975, 38009149085, 38072558056, 38215695691, 38422830017, 38451184548, 38451667997, 38486929114, 38490976280, +/// 38499044560, 38509976251, 38515330948, 38515815203, 38539153477, 38555189062, 38563270803, 38574220730, 38603446631, 38625121949, +/// 38654871669, 38719357870, 38769332102, 38834009252, 38834475422, 38863133731, 38863622360, 38899261248, 38903351774, 38911506495, +/// 38922555303, 38927967367, 38928456811, 38952045120, 38968252504, 38976420829, 38987488069, 39017027083, 39045506957, 39069003067, +/// 39074321000, 39074812283, 39114757593, 39122956627, 39134065476, 39134180145, 39160941512, 39160941512, 39163715544, 39226271968, +/// 39226271968, 39281309055, 39397624424, 39434582795, 39463823450, 39492946194, 39493442741, 39533816007, 39542102882, 39553330746, +/// 39583298473, 39611164966, 39640396442, 39640894843, 39658642925, 39677246509, 39681418846, 39689736660, 39701006445, 39702151829, +/// 39706526750, 39707025983, 39731086058, 39747617590, 39755949281, 39767237866, 39795580221, 39795580221, 39797367660, 39850383164, +/// 39857067678, 39916863784, 40011277739, 40011277739, 40040804482, 40040804482, 40041307917, 40041307917, 40078026772, 40078026772, +/// 40082241254, 40082241254, 40083528290, 40090643087, 40090643087, 40102026707, 40102026707, 40107602774, 40107602774, 40108107049, +/// 40108107049, 40132410155, 40132410155, 40149108672, 40149108672, 40157524522, 40157524522, 40168927134, 40168927134, 40181151147, +/// 40199361269, 40199361269, 40252912282, 40252912282, 40253099956, 40268086477, 40282805154, 40283311632, 40290860837, 40320064424, +/// 40320064424, 40320593902, 40321100855, 40324492364, 40332944976, 40344397398, 40362320218, 40370780759, 40374964479, 40382243924, +/// 40412839680, 40496194902, 40519786183, 40534183828, 40549688186, 40550198019, 40591651582, 40600160195, 40611634436, 40611688492, +/// 40642458087, 40654209068, 40659696920, 40659696920, 40689702172, 40689702172, 40690213765, 40690213765, 40699501154, 40722519509, +/// 40731810464, 40731810464, 40740348456, 40740348456, 40751916559, 40751916559, 40752571121, 40753083505, 40764491691, 40782792398, +/// 40782792398, 40794744473, 40803295658, 40809823227, 40814881634, 40845805179, 40877904439, 40885198892, 40905247372, 40905247372, +/// 40953897461, 40968449356, 40984119820, 40984635116, 41026532794, 41035132565, 41046784371, 41053640089, 41064857640, 41064857640, +/// 41077883618, 41083936055, 41084452605, 41126452325, 41135073040, 41142463123, 41146753224, 41172824637, 41173342305, 41177928213, +/// 41201224636, 41215432895, 41224072262, 41235777716, 41246781123, 41267020155, 41298180694, 41298180694, 41301569626, 41317584124, +/// 41390929077, 41423867162, 41471183566, 41493470843, 41513491214, 41524091387, 41524613471, 41536969936, 41567063158, 41567622580, +/// 41568145212, 41575776231, 41583245489, 41587581551, 41610639400, 41613932283, 41614455497, 41619090535, 41619361608, 41631179304, +/// 41656997027, 41662721320, 41665728952, 41677559814, 41684965139, 41688681106, 41695963084, 41709136970, 41726733058, 41727257691, +/// 41744056589, 41754506310, 41760242659, 41765522603, 41769914536, 41772975447, 41778670130, 41787818380, 41790533061, 41796343910, +/// 41796869418, 41803802253, 41804327855, 41822195812, 41834373399, 41839597425, 41842290058, 41842290058, 41847063487, 41848367626, +/// 41855835253, 41860250348, 41867720095, 41891965920, 41899441327, 41932819403, 41932819403, 41947771713, 41956535284, 41956535284, +/// 41987497551, 41987497551, 41988025462, 41988025462, 42017751313, 42025249166, 42030948884, 42030948884, 42039759195, 42039759195, +/// 42051696262, 42051696262, 42083556884, 42083556884, 42131559633, 42142409033, 42173508467, 42174038717, 42194924689, 42194924689, +/// 42201845839, 42209917551, 42209917551, 42214749442, 42217152297, 42226001639, 42226062877, 42226062877, 42226593788, 42226593788, +/// 42237991588, 42245902261, 42246433421, 42269761093, 42269761093, 42269993358, 42278621463, 42278621463, 42289621008, 42290626354, +/// 42290626354, 42298485541, 42310496072, 42322668002, 42322668002, 42323340298, 42342552775, 42354573252, 42355105779, 42360507948, +/// 42371684125, 42396913821, 42398404459, 42402952755, 42403485890, 42407291794, 42414910436, 42419333221, 42446210966, 42446744644, +/// 42446834028, 42449746627, 42449746627, 42451472384, 42455731515, 42467786695, 42469691106, 42490137005, 42499043569, 42499962570, +/// 42511111048, 42522454766, 42543319747, 42578937759, 42593904382, 42595447550, 42625337002, 42625872933, 42627573542, 42667019815, +/// 42669448412, 42671060904, 42678392562, 42690510967, 42698506391, 42699043241, 42722855590, 42742693521, 42750848781, 42750848781, +/// 42751653025, 42763792232, 42782397220, 42782397220, 42782935126, 42782935126, 42793904243, 42796192376, 42814339913, 42826671166, +/// 42826671166, 42835648272, 42835648272, 42843343871, 42843343871, 42847811330, 42847811330, 42851135823, 42874960567, 42874960567, +/// 42875499636, 42875499636, 42880275131, 42880275131, 42919330304, 42919330304, 42924692812, 42928326833, 42928326833, 42940516205, +/// 42940516205, 42951974507, 42951974507, 42973050245, 42973050245, 42974190865, 43009028035, 43009028035, 43025704592, 43025704592, +/// 43037051426, 43045882794, 43102081717, 43102081717, 43408273596, 43408273596, 43445782508, 43477843781, 43478390430, 43480689686, +/// 43480689686, 43520360250, 43522837419, 43531960452, 43544321225, 43552476558, 43553024145, 43577312740, 43597547431, 43604070657, +/// 43606686124, 43619068115, 43652116263, 43670626751, 43698411764, 43708158579, 43711593568, 43723126209, 43755392150, 43755942289, +/// 43783186707, 43800673013, 43809854284, 43822293964, 43855496086, 43884628792, 43884628792, 43917013915, 43917013915, 43917566086, +/// 43917566086, 43959954895, 43959959844, 43959959844, 43962462035, 43962462035, 43971553062, 43971677220, 43971677220, 43984162849, +/// 43984162849, 43987177202, 43992400559, 43992400559, 43992953678, 43992953678, 44004002332, 44004555597, 44017487612, 44017487612, +/// 44037926693, 44037926693, 44047157697, 44047157697, 44049540473, 44058773910, 44059664758, 44059664758, 44071284270, 44093046725, +/// 44093046725, 44104675041, 44111744188, 44111744188, 44149655125, 44149655125, 44179900474, 44225441114, 44225441114, 44237104345, +/// 44347570567, 44421553645, 44430922636, 44539133510, 44550884484, 44583761278, 44584321832, 44629899390, 44635497705, 44639254480, +/// 44647274103, 44651929665, 44680222029, 44680783796, 44685760364, 44726459965, 44735835295, 44748537904, 44760478660, 44782441799, +/// 44819934443, 44822691052, 44837313170, 44897466753, 44916906174, 45016306316, 45063498524, 45066263322, 45113702916, 45235990342, +/// 45311455532, 45319541129, 45518685373, 45518685373, 45549083567, 45719144915, 45720339981, 45732402599, 45766151306, 45766726727, +/// 45777314266, 45777314266, 45795416129, 45798822161, 45810905485, 45813513031, 45823116224, 45836127564, 45844712124, 45845288532, +/// 45870855474, 45892155149, 45901774826, 45914808501, 45916632484, 45949596024, 45969080748, 46008587936, 46015977015, 46087564913, +/// 46180954454, 46180954454, 46210167718, 46257996085, 46257996085, 46289490721, 46380436848, 46380436848, 46460065280, 46480784859, +/// 46480784859, 46503648831, 46767874109, 46929358864, 46929358864, 47001868597, 47134371115, 47215280578, 47268924669, 47384047456, +/// 47435261561, 47486566863, 47610475869, 47610475869, 47692202599, 47692202599, 47704780092, 47891699427, 47941906012, 47995317184, +/// 48125415655, 48205701144, 48214303205, 48333297308, 48426167684, 48426167684, 48437870498, 48640702875, 48701316363, 48701316363, +/// 48724198063, 48849533459, 48905331829, 48955223570, 49161818104, 49246207822, 49342963085, 49342963085, 49449720773, 49449720773, +/// 49615127444, 49700295300, 50145054511, 50231132024, 50465164177, 50651570207, 50651570207, 50738517190, 50738517190, 50751898064, +/// 51420561489, 51531814238, 52784267858, 52874875766] /// 6. The XRC then returns the median and the standard deviation. -/// a. The median rate from step 5 is 42397659140. -/// b. The standard deviation from step 5 is 2767790871. +/// a. The median rate from step 5 is 42278621463. +/// b. The standard deviation from step 5 is 2749287452. /// Fiat-crypto pair (retrieve EUR/BTC rate) /// 0. The instructions are similar to the crypto-fiat pair. The only difference is that the rates are inverted before /// being returned. -/// a. When inverted, the median rate is 23312466. -/// b. When inverted, the standard deviation is 1445944. +/// a. When inverted, the median rate is 23652616. +/// b. When inverted, the standard deviation is 1447308. /// Fiat pair (retrieve EUR/JPY rate) /// 0. The XRC retrieves rates from the mock forex sources. /// a. During collection the rates retrieved are normalized to USD. @@ -140,22 +146,20 @@ use crate::{ /// 1. The XRC divides EUR/USD by JPY/USD. The division inverts JPY/USD to USD/JPY then multiplies EUR/USD and USD/JPY /// to get the resulting EUR/JPY rate. /// a. EUR/JPY rates should then include: -/// [124030649755, 124092229644, 124094041743, 124102918437, 124189940312, 124358334787, 124533404687, 124852849994, 124934277074, -/// 131953042878, 132018556151, 132020483996, 132029927684, 132122508037, 132301658621, 132487911020, 132827760729, 132914388921, -/// 132995033068, 141490021504, 142296630547, 142367279300, 142369358266, 142379542230, 142479379808, 142672573719, 142723892446, -/// 142794753330, 142796838538, 142807053080, 142832027721, 142872584497, 142873426145, 142902532594, 142902942293, 142905029081, -/// 142907190432, 142915251362, 142943519205, 142945606586, 142955831769, 142973482171, 142975569989, 142985797316, 143004170223, -/// 143015464584, 143048618694, 143050417305, 143056073446, 143075170262, 143077259565, 143086060005, 143087494166, 143100964430, -/// 143119640802, 143121440305, 143121730754, 143123530284, 143131968536, 143133768195, 143155982847, 143187828165, 143209385395, -/// 143227058260, 143229149781, 143232333722, 143234134642, 143239395247, 143239916129, 143250049321, 143280076540, 143302419939, -/// 143333334966, 143339835761, 143381982692, 143410993537, 143426548595, 143428351957, 143451714709, 143481784200, 143534196401, -/// 143583833814, 143628462457, 143630268357, 143670010350, 143736261807, 143763709688, 143778862455, 143819688082, 143849834706, -/// 143872632785, 143913485038, 143943651322, 143952146091, 143996889212, 143998699745, 144046029434, 144090801735, 144092613449, -/// 144104965083, 144198948091, 152581197651, 153039340138, 153155290949, 153198778988, 153230891601, 153339875145, 153387536154, -/// 153389464760, 153502660110] +/// [124030649755, 124092229644, 124094041743, 124102918437, 124358334787, 124533404687, 124852849994, 124934277074, 131953042878, 132018556151, +/// 132020483996, 132029927684, 132301658621, 132487911020, 132827760729, 132914388921, 132995033068, 135589467313, 141490021504, 142296630547, +/// 142367279300, 142369358266, 142379542230, 142672573719, 142723892446, 142794753330, 142796838538, 142807053080, 142832027721, 142872584497, +/// 142873426145, 142902532594, 142902942293, 142905029081, 142915251362, 142943519205, 142945606586, 142955831769, 142973482171, 142975569989, +/// 142985797316, 143048618694, 143050417305, 143100964430, 143119640802, 143121440305, 143121730754, 143123530284, 143131968536, 143133768195, +/// 143155982847, 143209385395, 143227058260, 143229149781, 143239395247, 143239916129, 143250049321, 143280076540, 143302419939, 143333334966, +/// 143410993537, 143426548595, 143428351957, 143451714709, 143481784200, 143534196401, 143628462457, 143630268357, 143670010350, 143736261807, +/// 143763709688, 143778862455, 143819688082, 143849834706, 143872632785, 143913485038, 143943651322, 143996889212, 143998699745, 144090801735, +/// 144092613449, 144104965083, 144198948091, 144250173885, 146264455573, 146337074309, 146339211245, 146349679180, 146650881613, 146857334644, +/// 147234043901, 147330067646, 152581197651, 153039340138, 153155290949, 153198778988, 153230891601, 153387536154, 153389464760, 153502660110, +/// 155557713956, 156024793773, 156143006525, 156187342918, 156220081975, 156379782312, 156381748540, 156497152077, 156835799409, 159895313434] /// 2. The XRC then return the median and the standard deviation. -/// a. The median rate from the group of rates in step 1.a.: 143121585529. -/// b. The standard deviation of the group of rates in step 1.a.: 7028947458. +/// a. The median rate from the group of rates in step 1.a.: 143239655688. +/// b. The standard deviation of the group of rates in step 1.a.: 7823121871. #[ignore] #[test] fn basic_exchange_rates() { @@ -269,8 +273,8 @@ fn basic_exchange_rates() { exchange_rate.metadata.quote_asset_num_received_rates, NUM_FOREX_SOURCES ); - assert_eq!(exchange_rate.metadata.standard_deviation, 2_767_790_871); - assert_eq!(exchange_rate.rate, 42_397_659_140); + assert_eq!(exchange_rate.metadata.standard_deviation, 2_749_287_452); + assert_eq!(exchange_rate.rate, 42_278_621_463); // Fiat-crypto pair let fiat_crypto_pair_request = GetExchangeRateRequest { @@ -318,8 +322,8 @@ fn basic_exchange_rates() { exchange_rate.metadata.quote_asset_num_received_rates, NUM_EXCHANGES ); - assert_eq!(exchange_rate.metadata.standard_deviation, 1_445_944); - assert_eq!(exchange_rate.rate, 23_586_207); + assert_eq!(exchange_rate.metadata.standard_deviation, 1_447_308); + assert_eq!(exchange_rate.rate, 23_652_616); // Fiat-pair let fiat_pair_request = GetExchangeRateRequest { @@ -358,8 +362,8 @@ fn basic_exchange_rates() { exchange_rate.metadata.quote_asset_num_received_rates, NUM_FOREX_SOURCES ); - assert_eq!(exchange_rate.metadata.standard_deviation, 7_028_947_458); - assert_eq!(exchange_rate.rate, 143_121_585_529); + assert_eq!(exchange_rate.metadata.standard_deviation, 7_823_121_871); + assert_eq!(exchange_rate.rate, 143_239_655_688); Ok(()) }) diff --git a/src/xrc-tests/src/tests/get_icp_xdr_rate.rs b/src/xrc-tests/src/tests/get_icp_xdr_rate.rs index 99028b66..a83da881 100644 --- a/src/xrc-tests/src/tests/get_icp_xdr_rate.rs +++ b/src/xrc-tests/src/tests/get_icp_xdr_rate.rs @@ -42,20 +42,20 @@ use crate::{ /// 5. The XRC divides the ICP/USD by the forex rate CXDR/USD. The division works by inverting CXDR/USD to USD/CXDR then multiplying /// USD/CXDR and ICP/USD resulting in ICP/CXDR. /// i. For request 1, this results in the following rates: -/// [ 2830147844, 2830147844, 2830147844, 2830147844, 2837404634, 2837404634, 2838130313, 2838130313, 2844661423, 2844661423, -/// 2844661423, 2844661423, 2851918213, 2851918213, 2860468811, 2860468811, 2860468811, 2860468811, 2867803346, 2867803346, -/// 2868536800, 2868536800, 2875137882, 2875137882, 2875137882, 2875137882, 2882472418, 2882472418, 2902715738, 2902715738, -/// 2906344133, 2906344133, 2917678190, 2917678190, 2917678190, 2917678190, 2925159416, 2925159416, 2925907539, 2925907539, -/// 2932640642, 2932640642, 2932640642, 2932640642, 2933814166, 2933814166, 2937481433, 2937481433, 2940121869, 2940121869, -/// 2947149687, 2947149687, 2947149687, 2947149687, 2947149687, 2947149687, 2947149687, 2947149687, 2954706481, 2954706481, -/// 2954706481, 2954706481, 2955462160, 2955462160, 2955462160, 2955462160, 2962263275, 2962263275, 2962263275, 2962263275, -/// 2962263275, 2962263275, 2962263275, 2962263275, 2969820069, 2969820069, 2969820069, 2969820069, 2992490452, 2992490452, -/// 2996231065, 2996231065, 3022717627, 3022717627, 3022717627, 3022717627, 3026496024, 3026496024, 3026496024, 3026496024, -/// 3071240197, 3071240197, 3071240197, 3071240197, 3079115172, 3079115172, 3079902669, 3079902669, 3086990147, 3086990147, -/// 3086990147, 3086990147, 3094865122, 3094865122, 3149989946, 3149989946, 3153927433, 3153927433 ] +/// [ 2830209625, 2830209625, 2830209625, 2830209625, 2837466572, 2837466572, 2838192267, 2838192267, 2844723520, 2844723520, +/// 2844723520, 2844723520, 2851980468, 2851980468, 2860531253, 2860531253, 2860531253, 2860531253, 2867865948, 2867865948, +/// 2868599418, 2868599418, 2875200644, 2875200644, 2875200644, 2875200644, 2882535340, 2882535340, 2902779102, 2902779102, +/// 2906407576, 2906407576, 2917741881, 2917741881, 2917741881, 2917741881, 2925223271, 2925223271, 2925971409, 2925971409, +/// 2932704660, 2932704660, 2932704660, 2932704660, 2933878209, 2933878209, 2937545556, 2937545556, 2940186049, 2940186049, +/// 2947214021, 2947214021, 2947214021, 2947214021, 2947214021, 2947214021, 2947214021, 2947214021, 2954770980, 2954770980, +/// 2954770980, 2954770980, 2955526676, 2955526676, 2955526676, 2955526676, 2962327939, 2962327939, 2962327939, 2962327939, +/// 2962327939, 2962327939, 2962327939, 2962327939, 2969884898, 2969884898, 2969884898, 2969884898, 2992555776, 2992555776, +/// 2996296470, 2996296470, 3022783611, 3022783611, 3022783611, 3022783611, 3026562091, 3026562091, 3026562091, 3026562091, +/// 3071307240, 3071307240, 3071307240, 3071307240, 3079182387, 3079182387, 3079969902, 3079969902, 3087057534, 3087057534, +/// 3087057534, 3087057534, 3094932680, 3094932680, 3150058708, 3150058708, 3153996281, 3153996281 ] /// 6. The XRC returns the median rate and the standard deviation from the ICP/CXDR rates. -/// i. For request 1, the median rate is 2947149687. -/// ii. For request 1, the std dev is 83109681. +/// i. For request 1, the median rate is 2947214021. +/// ii. For request 1, the std dev is 83111496. fn get_icp_xdr_rate() { let now_seconds = time::OffsetDateTime::now_utc().unix_timestamp() as u64; let request_1_timestamp_seconds = now_seconds / 60 * 60; @@ -165,8 +165,8 @@ fn get_icp_xdr_rate() { exchange_rate.metadata.quote_asset_num_received_rates, NUM_FOREX_SOURCES ); - assert_eq!(exchange_rate.metadata.standard_deviation, 83_109_681); - assert_eq!(exchange_rate.rate, 2_947_149_687); + assert_eq!(exchange_rate.metadata.standard_deviation, 83_111_496); + assert_eq!(exchange_rate.rate, 2_947_214_021); let request = GetExchangeRateRequest { base_asset: Asset { @@ -203,8 +203,8 @@ fn get_icp_xdr_rate() { exchange_rate.metadata.quote_asset_num_received_rates, NUM_FOREX_SOURCES ); - assert_eq!(exchange_rate.metadata.standard_deviation, 91_016_291); - assert_eq!(exchange_rate.rate, 3_216_927_235); + assert_eq!(exchange_rate.metadata.standard_deviation, 91_018_277); + assert_eq!(exchange_rate.rate, 3_216_997_459); let request = GetExchangeRateRequest { base_asset: Asset { @@ -241,8 +241,8 @@ fn get_icp_xdr_rate() { exchange_rate.metadata.quote_asset_num_received_rates, NUM_FOREX_SOURCES ); - assert_eq!(exchange_rate.metadata.standard_deviation, 105_027_883); - assert_eq!(exchange_rate.rate, 3_899_305_739); + assert_eq!(exchange_rate.metadata.standard_deviation, 105_030_176); + assert_eq!(exchange_rate.rate, 3_899_390_858); Ok(()) }) diff --git a/src/xrc-tests/src/tests/misbehavior.rs b/src/xrc-tests/src/tests/misbehavior.rs index 3487bceb..708c198c 100644 --- a/src/xrc-tests/src/tests/misbehavior.rs +++ b/src/xrc-tests/src/tests/misbehavior.rs @@ -83,61 +83,35 @@ const FIAT_PAIR_COMMON_DATASET_STD_DEV: u64 = 396_623_626; /// 5. The XRC divides the BTC/USD by the forex rate EUR/USD. The division works by inverting EUR/USD to USD/EUR then multiplying /// USD/EUR and BTC/USD resulting in BTC/EUR. /// a. This results in the following rates: -/// [ 38422830017, 38451184548, 38451667997, 38463619538, 38486929114, 38490976280, 38499044560, 38509976251, 38515330948, 38515815203, -/// 38527786682, 38539153477, 38555189062, 38563270803, 38574220730, 38603446631, 38654871669, 38719357870, 38834475422, 38863133731, -/// 38863622360, 38875701944, 38899261248, 38903351774, 38911506495, 38922555303, 38927967367, 38928456811, 38940556547, 38952045120, -/// 38968252504, 38976420829, 38987488069, 39017027083, 39045506957, 39069003067, 39074321000, 39074812283, 39086957510, 39114757593, -/// 39122956627, 39134065476, 39134180145, 39163715544, 39281309055, 39463823450, 39492946194, 39493442741, 39505718086, 39533816007, -/// 39542102882, 39553330746, 39583298473, 39611164966, 39640396442, 39640894843, 39653216019, 39677246509, 39681418846, 39689736660, -/// 39701006445, 39702151829, 39706526750, 39707025983, 39719367714, 39731086058, 39747617590, 39755949281, 39767237866, 39797367660, -/// 39850383164, 39916863784, 40011277739, 40011277739, 40040804482, 40040804482, 40041307917, 40041307917, 40053753550, 40053753550, -/// 40078026772, 40078026772, 40082241254, 40082241254, 40090643087, 40090643087, 40102026707, 40102026707, 40107602774, 40107602774, -/// 40108107049, 40108107049, 40120573444, 40120573444, 40132410155, 40132410155, 40149108672, 40149108672, 40157524522, 40157524522, -/// 40168927134, 40168927134, 40199361269, 40199361269, 40252912282, 40252912282, 40253099956, 40282805154, 40283311632, 40295832484, -/// 40320064424, 40320064424, 40324492364, 40332944976, 40344397398, 40374964479, 40496194902, 40519786183, 40549688186, 40550198019, -/// 40562801825, 40591651582, 40600160195, 40611688492, 40642458087, 40659696920, 40659696920, 40689702172, 40689702172, 40690213765, -/// 40690213765, 40702861091, 40702861091, 40731810464, 40731810464, 40740348456, 40740348456, 40751916559, 40751916559, 40764491691, -/// 40782792398, 40782792398, 40905247372, 40905247372, 40953897461, 40984119820, 40984635116, 40997373953, 41026532794, 41035132565, -/// 41046784371, 41053640089, 41077883618, 41083936055, 41084452605, 41097222468, 41126452325, 41135073040, 41146753224, 41177928213, -/// 41201224636, 41301569626, 41493470843, 41524091387, 41524613471, 41537520145, 41567063158, 41575776231, 41587581551, 41619090535, -/// 41684965139, 41695963084, 41726733058, 41727257691, 41740227350, 41744056589, 41754506310, 41765522603, 41769914536, 41772975447, -/// 41778670130, 41790533061, 41796343910, 41796869418, 41803802253, 41804327855, 41809860714, 41817321469, 41822195812, 41839597425, -/// 41847063487, 41848367626, 41855835253, 41860250348, 41867720095, 41891965920, 41899441327, 41947771713, 42017751313, 42025249166, -/// 42131559633, 42142409033, 42173508467, 42174038717, 42187147245, 42194924689, 42194924689, 42201845839, 42214749442, 42217152297, -/// 42226001639, 42226062877, 42226062877, 42226593788, 42226593788, 42237991588, 42239718651, 42239718651, 42245902261, 42246433421, -/// 42259564450, 42269761093, 42269761093, 42269993358, 42278621463, 42278621463, 42289621008, 42290626354, 42290626354, 42298485541, -/// 42310496072, 42322668002, 42322668002, 42323340298, 42342552775, 42354573252, 42355105779, 42360507948, 42368270586, 42371684125, -/// 42396913821, 42398404459, 42402952755, 42403485890, 42407291794, 42416665734, 42419333221, 42446834028, 42449746627, 42449746627, -/// 42451472384, 42455731515, 42467786695, 42469691106, 42499962570, 42578937759, 42593904382, 42625337002, 42625872933, 42627573542, -/// 42639121900, 42667019815, 42669448412, 42678392562, 42690510967, 42698506391, 42699043241, 42712314951, 42722855590, 42742693521, -/// 42750848781, 42750848781, 42751653025, 42763792232, 42782397220, 42782397220, 42782935126, 42782935126, 42796192376, 42796232910, -/// 42796232910, 42814339913, 42826671166, 42826671166, 42835648272, 42835648272, 42847811330, 42847811330, 42851135823, 42880275131, -/// 42880275131, 42924692812, 42974190865, 43009028035, 43009028035, 43045882794, 43408273596, 43408273596, 43445782508, 43477843781, -/// 43478390430, 43480689686, 43480689686, 43491904376, 43520360250, 43522837419, 43531960452, 43544321225, 43552476558, 43553024145, -/// 43566561289, 43577312740, 43597547431, 43606686124, 43619068115, 43652116263, 43670626751, 43708158579, 43783186707, 43884628792, -/// 43884628792, 43917013915, 43917013915, 43917566086, 43917566086, 43931216537, 43931216537, 43959954895, 43959959844, 43959959844, -/// 43962462035, 43962462035, 43971553062, 43971677220, 43971677220, 43984162849, 43984162849, 43992400559, 43992400559, 43992953678, -/// 43992953678, 44004002332, 44004555597, 44006627560, 44006627560, 44017487612, 44017487612, 44018233085, 44037926693, 44037926693, -/// 44047157697, 44047157697, 44049540473, 44058773910, 44059664758, 44059664758, 44071284270, 44093046725, 44093046725, 44104675041, -/// 44111744188, 44111744188, 44149655125, 44149655125, 44225441114, 44225441114, 44237104345, 44347570567, 44421553645, 44430922636, -/// 44539133510, 44550884484, 44583761278, 44584321832, 44598179523, 44629899390, 44639254480, 44651929665, 44685760364, 44819934443, -/// 44822691052, 44897466753, 45016306316, 45066263322, 45235990342, 45311455532, 45319541129, 45549083567, 45719144915, 45720339981, -/// 45732402599, 45766151306, 45766726727, 45777314266, 45777314266, 45780951933, 45795416129, 45798822161, 45810905485, 45813513031, -/// 45823116224, 45836127564, 45844712124, 45845288532, 45859538157, 45870855474, 45892155149, 45901774826, 45914808501, 45916632484, -/// 45949596024, 45969080748, 46008587936, 46087564913, 46180954454, 46180954454, 46210167718, 46257996085, 46257996085, 46289490721, -/// 46380436848, 46380436848, 46460065280, 46767874109, 46929358864, 46929358864, 47134371115, 47215280578, 47268924669, 47384047456, -/// 47610475869, 47610475869, 47692202599, 47692202599, 47704780092, 47891699427, 48125415655, 48205701144, 48214303205, 48333297308, -/// 48640702875, 48701316363, 48701316363, 48724198063, 48849533459, 48905331829, 49161818104, 49246207822, 49342963085, 49342963085, -/// 49615127444, 49700295300, 50145054511, 50231132024, 50651570207, 50651570207, 50738517190, 50738517190, 50751898064, 51420561489, -/// 52784267858, 52874875766] +/// [ 37668988975, 38072558056, 38215695691, 38515330948, 38563270803, 38574220730, 38603446631, 38625121949, 38834009252, 38927967367, +/// 38976420829, 38987488069, 39017027083, 39074321000, 39122956627, 39134065476, 39163715544, 39226271968, 39226271968, 39397624424, +/// 39492946194, 39542102882, 39553330746, 39583298473, 39706526750, 39755949281, 39767237866, 39795580221, 39795580221, 39797367660, +/// 40107602774, 40107602774, 40157524522, 40157524522, 40168927134, 40168927134, 40199361269, 40199361269, 40282805154, 40330823314, +/// 40332944976, 40344397398, 40374964479, 40689702172, 40689702172, 40740348456, 40740348456, 40751916559, 40751916559, 40762910125, +/// 40782792398, 40782792398, 40877904439, 41236971036, 41246781123, 41288298504, 41300022195, 41317584124, 41331313309, 41471183566, +/// 41578168365, 41678765919, 41688681106, 41730643286, 41742492580, 41754506310, 41760242659, 41774118933, 41796343910, 41848367626, +/// 41860250348, 41891965920, 41998149859, 41998149859, 42173508467, 42201845839, 42226001639, 42237991588, 42245902261, 42269993358, +/// 42298485541, 42310496072, 42342552775, 42360507948, 42402952755, 42455731515, 42467786695, 42499962570, 42512341275, 42522454766, +/// 42565256190, 42577342470, 42595447550, 42609601350, 42625337002, 42678392562, 42690510967, 42698506391, 42722855590, 42751653025, +/// 42763792232, 42796192376, 42814339913, 42941758859, 42941758859, 42951974507, 42951974507, 42995208268, 42995208268, 43007416632, +/// 43007416632, 43025704592, 43025704592, 43040001359, 43040001359, 43045882794, 43477843781, 43480689686, 43480689686, 43531960452, +/// 43544321225, 43552476558, 43577312740, 43606686124, 43619068115, 43652116263, 43670626751, 43766492976, 43917013915, 43917013915, +/// 43971677220, 43971677220, 43984162849, 43984162849, 43992400559, 43992400559, 44017487612, 44017487612, 44047157697, 44047157697, +/// 44059664758, 44059664758, 44093046725, 44093046725, 44111744188, 44111744188, 44421553645, 44705038876, 44749832880, 44760478660, +/// 44805532791, 44818255191, 44837313170, 44852211907, 44897466753, 45066263322, 45183989122, 45311455532, 45549083567, 45720339981, +/// 45766151306, 45795416129, 45798822161, 45823116224, 45836127564, 45844712124, 45870855474, 45901774826, 45914808501, 45949596024, +/// 45969080748, 46087668945, 46210167718, 46257996085, 46257996085, 46289490721, 46460065280, 46553200949, 46553200949, 46929358864, +/// 46929358864, 47134371115, 47215280578, 47560549941, 47610475869, 47610475869, 47692202599, 47692202599, 48070092884, 48205701144, +/// 48513335687, 48640702875, 48724198063, 48905331829, 49031494785, 49161818104, 49246207822, 49526762404, 49526762404, 49615127444, +/// 49700295300, 50145054511, 50231132024, 50651570207, 50651570207, 50738517190, 50738517190, 51612099727, 52784267858, 52874875766] /// 6. The XRC then returns the median and the standard deviation. -/// a. The median rate from step 5 is 43479266733. -/// b. The standard deviation from step 5 is 1638074. +/// a. The median rate from step 5 is 42946866683. +/// b. The standard deviation from step 5 is 3202501200. /// Fiat-crypto pair (retrieve EUR/BTC rate) /// 0. The instructions are similar to the crypto-fiat pair. The only difference is that the rates are inverted before /// being returned. -/// a. When inverted, the median rate is 22999467. -/// b. When inverted, the standard deviation is 1638074. +/// a. When inverted, the median rate is 23284585. +/// b. When inverted, the standard deviation is 1650102. /// Fiat pair (retrieve EUR/JPY rate) /// 0. The XRC retrieves rates from the mock forex sources. /// a. During collection the rates retrieved are normalized to USD. @@ -151,13 +125,14 @@ const FIAT_PAIR_COMMON_DATASET_STD_DEV: u64 = 396_623_626; /// 1. The XRC divides EUR/USD by JPY/USD. The division inverts JPY/USD to USD/JPY then multiplies EUR/USD and USD/JPY /// to get the resulting EUR/JPY rate. /// a. EUR/JPY rates should then include: -/// [ 124092229644, 124102918437, 124358334787, 124852849994, 127158081968, 132018556151, 132029927684, 132301658621, 132827760729, -/// 132995033068, 135280238194, 141490021504, 142794753330, 142807053080, 142902942293, 142915251362, 142943519205, 142955831769, -/// 143100964430, 143121440305, 143133768195, 143209385395, 143250049321, 143428351957, 143670010350, 143778862455, 143819688082, -/// 143998699745, 146322674679, 146433536585, 146475115999, 146657432861, 153039340138, 153155290949, 153198778988, 153389464760 ] +/// [ 124092229644, 124102918437, 124358334787, 124852849994, 132018556151, 132029927684, 132301658621, 132827760729, 132995033068, 135589467313, +/// 141490021504, 142794753330, 142807053080, 142902942293, 142915251362, 142943519205, 142955831769, 143100964430, 143121440305, 143133768195, +/// 143209385395, 143250049321, 143428351957, 143670010350, 143778862455, 143819688082, 143998699745, 144250173885, 146337074309, 146349679180, +/// 146650881613, 147234043901, 153039340138, 153155290949, 153198778988, 153389464760, 156024793773, 156143006525, 156187342918, 156381748540, +/// 156835799409, 159895313434 ] /// 2. The XRC then return the median and the standard deviation. -/// a. The median rate from the group of rates in step 1.a.: 142800903205. -/// b. The standard deviation of the group of rates in step 1.a.: 17672086919. +/// a. The median rate from the group of rates in step 1.a.: 143229717358. +/// b. The standard deviation of the group of rates in step 1.a.: 9438739634. #[ignore] #[test] fn misbehavior() { @@ -285,14 +260,14 @@ fn misbehavior() { base_asset: btc_asset.clone(), quote_asset: eur_asset.clone(), timestamp: timestamp_seconds, - rate: 43_479_266_733, + rate: 42_946_866_683, metadata: ExchangeRateMetadata { decimals: 9, base_asset_num_queried_sources: NUM_EXCHANGES, base_asset_num_received_rates: NUM_EXCHANGES, quote_asset_num_queried_sources: NUM_FOREX_SOURCES, quote_asset_num_received_rates: NUM_FOREX_SOURCES, - standard_deviation: 3_220_024_900, + standard_deviation: 3_202_501_200, forex_timestamp: Some(yesterday_timestamp_seconds), }, }; @@ -319,14 +294,14 @@ fn misbehavior() { base_asset: eur_asset.clone(), quote_asset: btc_asset, timestamp: timestamp_seconds, - rate: 22_999_467, + rate: 23_284_585, metadata: ExchangeRateMetadata { decimals: 9, base_asset_num_queried_sources: NUM_FOREX_SOURCES, base_asset_num_received_rates: NUM_FOREX_SOURCES, quote_asset_num_queried_sources: NUM_EXCHANGES, quote_asset_num_received_rates: NUM_EXCHANGES, - standard_deviation: 1_638_074, + standard_deviation: 1_650_102, forex_timestamp: Some(yesterday_timestamp_seconds), }, }; @@ -360,14 +335,14 @@ fn misbehavior() { class: AssetClass::FiatCurrency, }, timestamp: yesterday_timestamp_seconds, - rate: 142_800_903_205, + rate: 143_229_717_358, metadata: ExchangeRateMetadata { decimals: 9, base_asset_num_queried_sources: NUM_FOREX_SOURCES, base_asset_num_received_rates: NUM_FOREX_SOURCES, quote_asset_num_queried_sources: NUM_FOREX_SOURCES, quote_asset_num_received_rates: NUM_FOREX_SOURCES, - standard_deviation: 17_672_086_919, + standard_deviation: 9_438_739_634, forex_timestamp: Some(yesterday_timestamp_seconds), }, }; diff --git a/src/xrc/src/forex.rs b/src/xrc/src/forex.rs index 8552d176..a8c30020 100644 --- a/src/xrc/src/forex.rs +++ b/src/xrc/src/forex.rs @@ -7,6 +7,7 @@ mod italy; mod myanmar; mod nepal; mod switzerland; +mod turkey; mod uzbekistan; use candid::{ @@ -224,7 +225,9 @@ macro_rules! forex { } -forex! { CentralBankOfMyanmar, CentralBankOfBosniaHerzegovina, EuropeanCentralBank, BankOfCanada, CentralBankOfUzbekistan, ReserveBankOfAustralia, CentralBankOfNepal, CentralBankOfGeorgia, BankOfItaly, SwissFederalOfficeForCustoms } +forex! { + CentralBankOfMyanmar, CentralBankOfBosniaHerzegovina, EuropeanCentralBank, BankOfCanada, CentralBankOfUzbekistan, ReserveBankOfAustralia, + CentralBankOfNepal, CentralBankOfGeorgia, BankOfItaly, SwissFederalOfficeForCustoms, CentralBankOfTurkey } #[derive(Debug)] pub struct ForexContextArgs { @@ -1487,7 +1490,7 @@ mod test { fn is_available_ipv4() { let available_forex_sources_count = FOREX_SOURCES.iter().filter(|e| e.is_available()).count(); - assert_eq!(available_forex_sources_count, 10); + assert_eq!(available_forex_sources_count, 11); } #[test] diff --git a/src/xrc/src/forex/turkey.rs b/src/xrc/src/forex/turkey.rs new file mode 100644 index 00000000..860525e6 --- /dev/null +++ b/src/xrc/src/forex/turkey.rs @@ -0,0 +1,168 @@ +use chrono::NaiveDateTime; +use serde::{de, Deserialize, Deserializer}; + +use crate::{ExtractError, ONE_DAY_SECONDS, ONE_KIB, RATE_UNIT}; +use super::{IsForex, CentralBankOfTurkey}; + +#[derive(Deserialize, Debug)] +struct XmlRdfEnvelope { + #[serde(rename = "Tarih")] + date: String, + #[serde(rename = "Currency")] + items: Vec, +} + +#[derive(Deserialize, Debug)] +struct XmlItem { + #[serde(rename = "ForexBuying", deserialize_with = "val_deserializer")] + forex_buying: String, + #[serde(rename = "ForexSelling", deserialize_with = "val_deserializer")] + forex_selling: String, + #[serde(rename = "Unit")] + unit: f64, + #[serde(rename = "CurrencyCode")] + currency_code: String, +} + +// Custom deserializer for handling empty tags in the XML to +// avoid serde_xml_rs UnexpectedToken errors. +fn val_deserializer<'de, D>(d: D) -> Result +where + D: Deserializer<'de>, +{ + let s = String::deserialize(d)?; + match &s[..] { + "" => Ok("0.0".to_string()), + _ => Ok(s.parse().map_err(de::Error::custom)?), + } +} + +impl IsForex for CentralBankOfTurkey { + fn get_base_url(&self) -> &str { + "https://www.tcmb.gov.tr/kurlar/YM/DMY.xml" + } + + // Override the default implementation of [get_url] of the [IsForex] trait. + fn get_url(&self, timestamp: u64) -> String { + let year_month = NaiveDateTime::from_timestamp_opt(timestamp as i64, 0) + .map(|t| t.format("%Y%m").to_string()) + .unwrap_or_default(); + + let day_month_year = NaiveDateTime::from_timestamp_opt(timestamp as i64, 0) + .map(|t| t.format("%d%m%Y").to_string()) + .unwrap_or_default(); + + self.get_base_url() + .replace("YM", &year_month) + .replace("DMY", &day_month_year) + } + + fn extract_rate(&self, bytes: &[u8], timestamp: u64) -> Result { + let timestamp = (timestamp / ONE_DAY_SECONDS) * ONE_DAY_SECONDS; + + let data: XmlRdfEnvelope = serde_xml_rs::from_reader(bytes) + .map_err(|e| ExtractError::XmlDeserialize(format!("{:?}", e)))?; + + let date = format!("{} 00:00:00", data.date); + let extracted_timestamp = NaiveDateTime::parse_from_str(&date, "%d.%m.%Y %H:%M:%S") + .map(|t| t.timestamp()) + .unwrap_or_else(|_| { + NaiveDateTime::from_timestamp_opt(0, 0) + .map(|t| t.timestamp()) + .unwrap_or_default() + }) as u64; + + if extracted_timestamp != timestamp { + return Err(ExtractError::RateNotFound { + filter: "Cannot find data for timestamp".to_string(), + }); + } + + let mut rate_map = data + .items + .iter() + .filter_map(|item| { + let buying = item.forex_buying.parse::().unwrap_or_default(); + let selling = item.forex_selling.parse::().unwrap_or_default(); + if buying == 0.0 || selling == 0.0 { + None + } + else { + // Return the average of the buying and selling rates. + let rate = (buying + selling) / 2.0; + Some(( + item.currency_code.clone().to_uppercase(), + (RATE_UNIT as f64 * rate / item.unit) as u64 + )) + } + }) + .collect::(); + + if rate_map.is_empty() { + return Err(ExtractError::RateNotFound { + filter: "No rates found".to_string(), + }); + } + + rate_map.insert("TRY".to_string(), RATE_UNIT); + + self.normalize_to_usd(&rate_map) + } + + fn get_utc_offset(&self) -> i16 { + 3 + } + + fn max_response_bytes(&self) -> u64 { + 500 * ONE_KIB + } + + fn supports_ipv6(&self) -> bool { + false + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::{forex::Forex, utils::test::load_file}; + + /// The function test if the macro correctly generates the + /// [core::fmt::Display] trait's implementation for [Forex]. + #[test] + fn to_string() { + let forex = Forex::CentralBankOfTurkey(CentralBankOfTurkey); + assert_eq!(forex.to_string(), "CentralBankOfTurkey"); + } + + /// The function tests if the macro correctly generates derive copies by + /// verifying that the forex sources return the correct query string. + #[test] + fn query_string() { + let timestamp: u64 = 1706677200; + let forex = CentralBankOfTurkey; + assert_eq!( + forex.get_url(timestamp), + "https://www.tcmb.gov.tr/kurlar/202401/31012024.xml" + ); + } + + /// This function tests that the forex sources can report the max response bytes needed to make a successful HTTP outcall. + #[test] + fn max_response_bytes() { + let forex = Forex::CentralBankOfTurkey(CentralBankOfTurkey); + assert_eq!(forex.max_response_bytes(), 500 * ONE_KIB); + } + + /// The function tests if the [CentralBankOfTurkey] struct returns the correct forex rate. + #[test] + fn extract_rate() { + let forex = CentralBankOfTurkey; + let query_response = load_file("test-data/forex/central-bank-of-turkey.xml"); + let timestamp = 1706677200; + let extracted_rates = forex.extract_rate(&query_response, timestamp); + + assert!(matches!(extracted_rates, Ok(ref rates) if rates["CHF"] == 1_158_346_373)); + assert!(matches!(extracted_rates, Ok(ref rates) if rates["JPY"] == 6_768_796)); + } +} \ No newline at end of file diff --git a/src/xrc/src/periodic.rs b/src/xrc/src/periodic.rs index e0cfda80..05d9f55e 100644 --- a/src/xrc/src/periodic.rs +++ b/src/xrc/src/periodic.rs @@ -470,7 +470,7 @@ mod test { let timestamp = 1680220800; let forexes_with_timestamps_and_context = get_forexes_with_timestamps_and_context(timestamp); - assert_eq!(forexes_with_timestamps_and_context.len(), 10); + assert_eq!(forexes_with_timestamps_and_context.len(), 11); assert!(matches!( forexes_with_timestamps_and_context[0].0, diff --git a/src/xrc/test-data/forex/central-bank-of-turkey.xml b/src/xrc/test-data/forex/central-bank-of-turkey.xml new file mode 100644 index 00000000..09b9c06e --- /dev/null +++ b/src/xrc/test-data/forex/central-bank-of-turkey.xml @@ -0,0 +1,257 @@ + + + + + 1 + ABD DOLARI + US DOLLAR + 30.2952 + 30.3497 + 30.2740 + 30.3953 + + + + + 1 + AVUSTRALYA DOLARI + AUSTRALIAN DOLLAR + 19.8780 + 20.0076 + 19.7866 + 20.1277 + 1.5205 + + + + 1 + DANİMARKA KRONU + DANISH KRONE + 4.3914 + 4.4129 + 4.3883 + 4.4231 + 6.8881 + + + + 1 + EURO + EURO + 32.7884 + 32.8475 + 32.7655 + 32.8968 + + 1.0823 + + + 1 + İNGİLİZ STERLİNİ + POUND STERLING + 38.3398 + 38.5397 + 38.3130 + 38.5975 + + 1.2677 + + + 1 + İSVİÇRE FRANGI + SWISS FRANK + 35.0115 + 35.2363 + 34.9590 + 35.2891 + 0.8633 + + + + 1 + İSVEÇ KRONU + SWEDISH KRONA + 2.8965 + 2.9265 + 2.8945 + 2.9332 + 10.41 + + + + 1 + KANADA DOLARI + CANADIAN DOLLAR + 22.5412 + 22.6429 + 22.4578 + 22.7289 + 1.3422 + + + + 1 + KUVEYT DİNARI + KUWAITI DINAR + 97.9331 + 99.2145 + 96.4641 + 100.7027 + + 3.2509 + + + 1 + NORVEÇ KRONU + NORWEGIAN KRONE + 2.8847 + 2.9041 + 2.8827 + 2.9108 + 10.48 + + + + 1 + SUUDİ ARABİSTAN RİYALİ + SAUDI RIYAL + 8.0785 + 8.0930 + 8.0179 + 8.1537 + 3.7501 + + + + 100 + JAPON YENİ + JAPENESE YEN + 20.4569 + 20.5924 + 20.3812 + 20.6706 + 147.74 + + + + 1 + BULGAR LEVASI + BULGARIAN LEV + 16.6706 + 16.8887 + + + 1.8071 + + + + 1 + RUMEN LEYİ + NEW LEU + 6.5520 + 6.6378 + + + 4.5979 + + + + 1 + RUS RUBLESİ + RUSSIAN ROUBLE + 0.33575 + 0.34014 + + + 89.73 + + + + 100 + İRAN RİYALİ + IRANIAN RIAL + 0.07173 + 0.07267 + + + 42000 + + + + 1 + ÇİN YUANI + CHINESE RENMINBI + 4.1964 + 4.2514 + + + 7.1788 + + + + 1 + PAKİSTAN RUPİSİ + PAKISTANI RUPEE + 0.10867 + 0.11010 + + + 277.21 + + + + 1 + KATAR RİYALİ + QATARI RIAL + 8.2637 + 8.3718 + + + 3.6455 + + + + 1 + GÜNEY KORE WONU + SOUTH KOREAN WON + 0.02258 + 0.02288 + + + 1334 + + + + 1 + AZERBAYCAN YENİ MANATI + AZERBAIJANI NEW MANAT + 17.7208 + 17.9527 + + + 1.7000 + + + + 1 + BİRLEŞİK ARAP EMİRLİKLERİ DİRHEMİ + UNITED ARAB EMIRATES DIRHAM + 8.2019 + 8.3093 + + + 3.6730 + + + + 1 + ÖZEL ÇEKME HAKKI (SDR) + SPECIAL DRAWING RIGHT (SDR) + 40.3103 + + + + + 1.32939 + +