use crate::cell::BoC;
use crate::cell::TonHash;
use crate::cell::cell_parser::CellParser;
use crate::cell::ton_cell::TonCell;
use num_bigint::{BigInt, BigUint};
use std::str::FromStr;
use tokio_test::assert_ok;
#[test]
fn test_build_parse_bit() -> anyhow::Result<()> {
let mut writer = TonCell::builder();
writer.write_bit(true)?;
writer.write_bit(false)?;
writer.write_bit(true)?;
writer.write_bit(false)?;
let cell = writer.build()?;
let mut reader = CellParser::new(&cell);
assert!(reader.read_bit()?);
assert!(!reader.read_bit()?);
assert!(reader.read_bit()?);
assert!(!reader.read_bit()?);
Ok(())
}
#[test]
fn test_build_parse_bits() -> anyhow::Result<()> {
let mut writer = TonCell::builder();
writer.write_bit(true)?;
writer.write_bits([0b1010_1010], 8)?;
writer.write_bits([0b0101_0101], 4)?;
let cell = writer.build()?;
let mut reader = CellParser::new(&cell);
assert!(reader.read_bit()?);
let dst = reader.read_bits(8)?;
assert_eq!(dst, vec![0b1010_1010]);
let dst = reader.read_bits(4)?;
assert_eq!(dst, vec![0b0101_0000]);
Ok(())
}
#[test]
fn test_build_parse_num() -> anyhow::Result<()> {
let mut writer = TonCell::builder();
writer.write_num(&1u8, 4)?;
writer.write_num(&2u16, 5)?;
writer.write_num(&5u32, 10)?;
writer.write_num(&-1i8, 8)?;
writer.write_num(&-2i16, 16)?;
writer.write_num(&-5i32, 32)?;
let cell = writer.build()?;
let mut reader = CellParser::new(&cell);
assert_eq!(reader.read_num::<u8>(4)?, 1);
assert_eq!(reader.read_num::<u16>(5)?, 2);
assert_eq!(reader.read_num::<u32>(10)?, 5);
assert_eq!(reader.read_num::<i8>(8)?, -1);
assert_eq!(reader.read_num::<i16>(16)?, -2);
assert_eq!(reader.read_num::<i32>(32)?, -5);
Ok(())
}
#[test]
fn test_build_parse_bigint() -> anyhow::Result<()> {
let values = vec![
(BigInt::from(1), 4),
(BigInt::from(2), 5),
(BigInt::from(5), 10),
(BigInt::from(-1), 8),
(BigInt::from(-2), 16),
(BigInt::from(-5), 32),
(BigInt::from(-5), 32),
(BigInt::from_str("97887266651548624282413032824435501549503168134499591480902563623927645013201")?, 257),
];
let mut writer = TonCell::builder();
for (value, bits) in &values {
writer.write_num(value, *bits)?;
}
let cell = writer.build()?;
let mut reader = CellParser::new(&cell);
for (value, bits) in &values {
let read_value = reader.read_num::<BigInt>(*bits)?;
assert_eq!(read_value, *value);
}
Ok(())
}
#[test]
fn test_build_parse_biguint() -> anyhow::Result<()> {
let values = vec![
(BigUint::from(1u32), 4),
(BigUint::from(1u32), 5),
(BigUint::from(1u32), 10),
];
let mut writer = TonCell::builder();
for (value, bits) in &values {
writer.write_num(value, *bits)?;
}
let cell = writer.build()?;
let mut reader = CellParser::new(&cell);
for (value, bits) in &values {
let read_value = reader.read_num::<BigUint>(*bits)?;
assert_eq!(read_value, *value);
}
Ok(())
}
#[test]
fn test_merkle_proof() -> anyhow::Result<()> {
let boc_hex = "b5ee9c72010270010012ea0004993523881f0000000000000000a66fc77a4e821f4c129f912bc6644439d1ac63dd9b6f580cd1e94e2b5f7dccf8cacea7b04ed9405d653a230b52aac60ff91331bb0e878e9a487f7daa8c7be315c066301d011248fe2a8c42614d68d12aac795123b0f0f08723ca54701bec967057c65bc7b934c40007a66fc77a4e821f4c129f912bc6644439d1ac63dd9b6f580cd1e94e2b5f7dccf8000000001402094603bf9e1b33a424d7d7593a6ca3ffb83e5522e6428d85d33e8994f96a44a2a13b0c016f03245b9023afe2ffffff1100ffffffff0000000000000000022451230000000165c334120000286f923dbb04022451206013120f042455cc26aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac236870bdb78c3697e0a09060528480101b20e36a3b36a4cdee601106c642e90718b0a58daf200753dbb3189f956b494b6000122bf000128c257f5000817706000050df243e6d0880001437c112edc38112280fde9cf40a0c85bf0f71835129709df1dbf902ef3cef1cd6e1c50478343e54d32299afe0de28a0ebc3b62f2b88763cc0c35640be1756cb61d4e36eccf11e26272d0be080728480101fd99c10104b498a45bd1c30433496f3178a3060b3fc45c29615c27349a1689b30011284801019a92f0a65c9b1f4270b218a593ced06a6d24419c39af0bcda3422bf1b3a4ead6001a284801018138e3372827ff81e5a98f41ba062a4052a780c579ff6e11d57203ee16be4e2700112103d0400b2201c00e0c01db5013e99de0112289180001437c9173c6000001437c9173c6c3d6b8b525832e8dc440d0d7961eec1144afcbe540caa079966f7c2bcd36a5e1e5bd8636c59f2700884001e2902a2a7c5b589073fc76f582d4bbff52f4949d9840000040d4fe0000000000000000112289032e19a06a0d00134af19aabd21dcd65002028480101f320fd1f53a51f843a1f4dbdabd1673b8d79370a24c3341be1fa06868ba62d20000122330000000000000000ffffffffffffffff819e03fe7d1eba482828111028480101dc9e1ac7d5a3b499da8b6d0b3f00e22b532f75684d5d63b4e9566799d20453fd001c28480101a5a7d24057d8643b2527709d986cda3846adcb3eddc32d28ec21f69e17dbaaef0001284801011667641019e9dd09a298c6d4eab1e1bba2355753a99b7d31243b6c42efc1a4dc016e284801018a0ebc4b269be153abc0e9fb87cab259c090efa4f4d33fb125268263f6719f680001094603a66fc77a4e821f4c129f912bc6644439d1ac63dd9b6f580cd1e94e2b5f7dccf8001615241011ef55aaffffff111b1a1716284801018f98cf4eaa2989c1abcb2366a7a8ae57c6d570a095d766d064d811c50b3b28c600072a8a04a8bf744b6d4d98dd5e5beaeefd2055eef9ad734034dff100f4d21e95bdc1c935bf9e1b33a424d7d7593a6ca3ffb83e5522e6428d85d33e8994f96a44a2a13b0c016f016f1918688c0103bf9e1b33a424d7d7593a6ca3ffb83e5522e6428d85d33e8994f96a44a2a13b0c1a19b8b7f86e3fe862006c1ea6efab91393c668ca39ff753b99597865ec69fd4016f0014688c0103a8bf744b6d4d98dd5e5beaeefd2055eef9ad734034dff100f4d21e95bdc1c935328148a7197e88d36c73482b77a4642c21d5a3b7833ff1ec2023b1746544b6eb016f0014284801012c5b49e84ed5a2d81f8c36d856e86424e73a33200f4cb2a9d90fcf0ee6c1cc56000301a09bc7a987000000000401022451230000000100ffffffff000000000000000065c334120000286f923dbb000000286f923dbb04b86e5cc400081770022451200224501fc400000005000000000000002e1c00980000286f921f368402245122f9279cbc992ce04141a46dcbf95179a539a3bf0f19c5ff5151ce1acd04cbd58d9c209bd21923a5de79f35b9ade10e4d2c22a6fdb54cfb13c31936bdb0022dafa12674bf31a6b15281583a87f3ea90ca7baa6aefb888f6d1b800cbe29a283ab23c7d60008c00cacea7b04ed9405d653a230b52aac60ff91331bb0e878e9a487f7daa8c7be315226889a432e199f900000a1be474bad0c1340221e02a58004998802c174a3e2eb400e6c96fd6abfb4ba30b014f757c425b3b6c78ba3def4d0012a05c234b3dec5686cd8befd922011475a61187d4bc17c516cdb02145f5da1cc000000000000000000000001970ccfca211f01677038d7ea4c6800065af3107a40005174876e8000000000000000000000000000034bc00000000000076a700000000000076a700820009d801fd2b2c1b0de9638f907eb23492e10eb015cf33b88d088cad5b702837e2aadbe1003fa5658361bd2c71f20fd646925c21d602b9e67711a11195ab6e0506fc555b7c0000000038b3973f8064004b20014062d79883d20000000020114ff00f4a413f4bcf2c80b23020162252400fba0df8de003e008e1f047f087f09f41732661f0ab3bf047f087f0a141732661f0adbdc5f08a4351024e215209f083f085f087f089f08bf08df08ff093f095f097f099f09bf09df09ff0a1f0a3f0a5f0a7f0a9f0abf0ac2228222c22282226222a22262224222822242222222622222220222422201e22221e1c22201caa3b0202cd27260071d387c11fc21e1804bfc21fc28d05b046f7c2250db04fc22fc2a5400d4411806f05b59d3b2000054827c2390d07c33fc2400d07c347c11fc3240201202928005d4f84af849c8f845fa02f846fa02f847fa02f848fa02cb0fc9f844f843c8f841cf16f842cf16cb3fcb3fccccc9ed5480201202b2a00f33b51343e90007e187e90007e18b4cfc07e18f4cfc07e193500743e80007e197e80007e19be80007e19fe80007e1a34c3cc3e1a750c3e1abe12b43e80007e1afe80007e1b3e80007e1b74cfc07e1bb4cfc07e1bf4cfc07e1c34cfc07e1c750c343e90007e1cbe90007e1cf4cfc07e1d34c3c07e1d74c3cc3e1da003d90cc8b5d27087e4c0b4c7e4c09c0078807e1dc835d2708fe4b4cfe49c0078807e1e00b41d35c87e900c3e1e7c007e15e084067422e2aea3cc0c3e15e08407acc1da2ea3a8be15e0841d6bc46aaea3857e167e1071c17cb8af7e800c1c3e1196286d827e19b8c3b8c378c37c00a02f2e2c01fe31f859f842c705f2e2bdf823f843f84ea0bef2e2c082100ee6b280bef2e2c1f845f00470f823f843f84fa0b99b30f8555210a8812710a9048e15f823f843f850a0b99b30f8565210a8812710a904dee2f849c8f842cf16cb0f58fa0201fa02f847fa02f848fa02c9f858821023e0924ec8cb1fcb3ff852cf16f853cf16ccc92d006e718018c8cb05f841cf1682100bebc200fa02cb6accc971fb00708010c8cb05f842cf1621fa02cb6ac9810082fb0070f86570f86770f86800b8f859f841c705f2e2bdfa0030f004f843c822fa02f845f846a0fa02cb3ff847fa02f848fa02c9f849f85882102c570e27c8cb1fcb3ff852cf16f842cf16cb0fccc9718018c8cb05f841cf1670fa02cb6accc98040fb00f84601a0f86600f8f857820b65aa20ba8e6bf859f841c705f2e2bdfa003070f84622a1b609f866f84cf845a121b60820c2009ff004f84521a0f865f823f86370f868de5cbc8e33f849f858821071885e93c8cb1fcb3ff852cf16f842cf16cb0f59a1fa02c9718018c8cb05f841cf1670fa02cb6accc98040fb00915be29530840ff2f0e219463c5eebc769076e8f55bfb239d1c69b13088a4b8e8fcdfc9e848617a252e923e5001a037db935542d719081d4ebcc2ec19ddbe23277aa6ef55aa1e39af87511eff6227c01d331235b9023afe2ffffff1101000000008000000000000000027d33bc0000000165c3340d0000286f922e78d8022451202065333221d9800001002000000060b00e4149948c0c81bc73c8b6300a128ba6694eda18e19410000286f9200b20402245120f15b1ab07b52f36e9455d07f3bbaeaeb816fa8624539d4040fc632b80359686ced6506f6a195c77261a59c7b47f0c277e05ca7947a2affec9f5a76c8d686c8a783522138206f1cf22d8c0284a30343523135040de39e45b1805094664363528480101bb06f3506745c5f6a6239d132a70b38439cb60ff95f62e45261ba12e844e889b00012313010299ec5c523a20acb839383728480101ad57660aa9d96ef8477829d1a127963b0009a006126c46ff8183902609cbf1a4000128480101fdbbed5496b6556c9a90e289e70af7f60f2a4a9e3f963965525af8966ef964b001bd231301002f2af595dc0c85383b3a3c28480101f2f6fe016b51fb4e9b072d395f6e45dccd98ce6f1fbdd8f8a4d9051255eafd2801ce231100f07dd44eef15b318633d3c284801018abfab6d5739a7257d8f42f800d602e206fa344b5ef81fad6dba5f3a5c3dea410000221100ebee32c9f0560e683f3e28480101f2df4c577de71e407fb39e4d505b231adebe62dd308cc573fadf599b983ffe9d0065221100e2c4703c14120f486240221100e2857544c815648842412848010194261c3324c8cc35ff057611acf28187f4a7226beecab589a1d97e3791185eb80182221100e2628b741aab22c86143220f00cae3ebbf094ba86044220f00c4a7013b7fd32846452848010166422de0d702df9f7cf7313b3df3dc61bb70ebd4bacc02aa4a89434d37d40d840061220f00c269edc1b11228484728480101ac81e80417e6a67be41ec090987b76072e34e8b3f5a4da7d103595bc6f213590001c220f00c10db9deb35c085f49220f00c06d27874d03085e4a220d00b5bac0a80ae85d4b220d00ad1961518e084d4c28480101c32d351a62bb8df50ca3a4124c5d702742d7070845c5134e65d3044664632e200016220d00a541f522c5085c4e220d00a1b8f2227f88504f284801016fe4ca7f2fd9996c9f60c7caf4e24f454602bc050f3d63531318b5b5548aa2910011220d00a0c363afed885b51220d00a02c1c6061c853522848010120b1c091c3fc81f969ca06e6720937d01377137c85a7534a29f13e263a04b3cb000e220b008904273088555428480101d6ea177916d37bfd138f5d2111ee8cc29f02b776cd7c125b75e69ae7a25462f2000e220300085a56220300085957218fba7609db280baca744616a5558c1ff22663761d0f1d3490fefb5518f7c62a007409cc34aeafce4b16ef579a752ad76803359a8c0d1dd62bb44a30cb2c39816b80001437c8e975a0c58284801014bf31a6b15281583a87f3ea90ca7baa6aefb888f6d1b800cbe29a283ab23c7d60008284801013df0d5ae3c38e22cf11948609fd55e8d8c5751a5403835cb5854298bc07e912e0008284801014ab97878e707f6b7a6b66f80061e2a91c771e7c8d70363225b61862b708dd148000828480101d5f9f1bc6f5da130c2b22add929709f90a10d9bd7a060404776049183b534046000f28480101d8b6cca382ed037e921699461d90180000169b579a04c79829eb38eb947692090013284801012ccf4b7628e9ef3a81fd08a149df277b1f4c9cb373bf046ff668dc659b28109700172848010183c56d32cb572d19475384c2555dfaeda60e09df90e968592270b7058458c842001a28480101e16094e54cc07625daeb7ab01b2121f89b83883198ff0ac51356d629e49c162d001a284801012ca267bada1fe173a095ee83825158560f8a561cfa79eac126104d7fca444843001f284801015b0eb0ea082af45f1f0057576551d4920527d7272ae9272978a631785f45140f002a284801015d65d1c9dcd43cd4b9cb4b286622b6511e6c0ac8d894cce2cf0c3c6b7fde4e7e00ef2848010195ea62fad5502dd374c45b514f97aad280f42a01e20f69dcbba85475757b173a00ec28480101cdf8d708767621acc0f47543982ba574efb683dbe88bb1fb29758d00937edd4c01be28480101880edce964d5939a4baecf08bcec926d26cfdfdc4c7e82e524144847a0ad65eb00150946037ad716a4b065d1b8881a1af2c3dd822895f97ca819540f32cdef8579a6d4bc3c001f67241011ef55aaffffff116d6c696828480101639633e000afda58a8a6fe8683dda20ee9b9a03d07cb46424d66ba9aecbdc75000192a8a04ecf42a8d40d8a410ddc50b0b98425408e3e606c41ac05db9c90e8197db2a2c137db935542d719081d4ebcc2ec19ddbe23277aa6ef55aa1e39af87511eff6227c01d301d36b6a688c01037db935542d719081d4ebcc2ec19ddbe23277aa6ef55aa1e39af87511eff6227c177f5ba97c50ca4c1e7cd8cc5cdc6b9086b0e38ab15ab94036c6eebe46b2f74101d3001d688c0103ecf42a8d40d8a410ddc50b0b98425408e3e606c41ac05db9c90e8197db2a2c131fdf26006b5ea2aaa0786b51eac252d5a428c18fc1c2c55a98fc75b3a1e8f89301d3001c284801012bf865c8703e0c3bf380fce8bd7e34d58fdaaf57d17203625338ff91e2d6d4d0000302a09bc7a987000000008001027d33bc000000010100000000800000000000000065c3340d0000286f922e78c00000286f922e78d8ac97745d00081a9f022451200224501fc400000005000000000000002e6f6e00980000286f921f369c027d33bb863fdf6f8b28aa8dde268c2bd7d53f743508299135872dc08595529511c3f469c61f3d34b73e081fef5af0c33c660293a6ef93b86ba149f8d6b07bab494d3bf500980000286f9200b20402245120f15b1ab07b52f36e9455d07f3bbaeaeb816fa8624539d4040fc632b80359686ced6506f6a195c77261a59c7b47f0c277e05ca7947a2affec9f5a76c8d686c8a7";
let expected_hash = TonHash::from_str("60081a3bc1e907876b3f20889100d25d86cf07b2c23f10adfcb51eae7de53ac0")?;
let cell = BoC::from_hex(boc_hex)?.single_root()?;
assert_eq!(cell.hash()?, &expected_hash);
Ok(())
}
#[test]
fn test_build_parse_shard_block() -> anyhow::Result<()> {
let boc_hex =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/resources/tests/shard_block_6000000000000000_52111590.hex"));
let cell = BoC::from_hex(boc_hex)?.single_root()?;
assert_ok!(cell.hash());
let serialized = BoC::new(cell.clone()).to_hex(false)?;
let parsed_back = BoC::from_hex(&serialized)?.single_root()?;
assert_eq!(cell, parsed_back);
Ok(())
}
#[test]
fn test_fuzz_bocs() -> anyhow::Result<()> {
// https://github.com/ston-fi/tonlib-rs/issues/76
for boc_hex in &[
"b5ee9c725e0000030000000000000000000000000000000000005e",
"b5ee9c72c9000001000000000000100000000000000000ff20d1fffe20000052180000001926",
"b5ee9c7201000001000056600000000c000c0cff5e0000005eb5ee9c72ca0c0c0c0c0c0c00",
"b5ee9c72ca0000010000560c0c130c0c0c0c0c0c0c0c000c0c0c5e5e0c0c00b5ee0c5e5e",
"b5ee9c72ca0000230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000c000c0cffffffffffff0000000000000000000000000000000000000000000600080c",
"b5ee9c72d1000c0c0c0c20260cba5e0900002a2600000000000000090909090909090909090909090909090909090909091f1f1f1f090909090909090909090971ee31310909090909090909090200000900090909090901680909090909090909090909090909090909090909090000000000000000000000000c88f3",
"b5ee9c72ca0000180000250125000000000000000b0b0b0b0b0b0404040404040404030404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040408080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808040404040c04040404040404040404040404040404040404040404040404040404040404040404040404270404040404040404040404040404040404040400005204040404040404040404000404040404040404040404040404040403fb04040404040404040404040404040404040404040404040400002501250b4b0b0800ca00250c00000c000c100c0c0c26",
"b5ee9c72d1000a000000000000000008860101ff041cffff000100000000000010081c01000000000000000000000000000000000000b5ee00000000ff9c72d1000a0000000000000000000000ac0000000006060606060606060606060606000008d60104ff031cff530000002e0000080000000000000000b0504f4f4ab0b0b0b0b0b0b0b0b00f00b00500000f0000000000030053a900002f00000000000000feffffffff0000000000009ce4ee6100000000000000000000000000000886fc00ff041cffff00000000000063000000000000eeee9c72069c720606060000060600",
] {
let _boc = BoC::from_hex(boc_hex);
}
Ok(())
}