| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232 |
- // SPDX-License-Identifier: Apache-2.0
- use crate::{build_solidity, BorshToken, Pubkey};
- use num_bigint::BigInt;
- use num_traits::{One, Zero};
- #[test]
- fn fixed_array() {
- // test that the abi encoder can handle fixed arrays
- let mut vm = build_solidity(
- r#"
- contract foo {
- function get() public returns (uint32[4] f, bytes1 g) {
- f[0] = 1;
- f[1] = 102;
- f[2] = 300331;
- f[3] = 12313231;
- g = 0xfe;
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm.function("get").call().unwrap().unwrap_tuple();
- assert_eq!(
- returns,
- vec![
- BorshToken::FixedArray(vec![
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(1u8),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(102u8),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(300331u32),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(12313231u32),
- },
- ]),
- BorshToken::uint8_fixed_array(vec!(0xfe))
- ]
- );
- // let's make it more interesting. Return some structs, some of which will be null pointers
- // when they get to the abi encoder
- let mut vm = build_solidity(
- r#"
- struct X {
- uint32 f1;
- bool f2;
- }
- contract foo {
- function get() public returns (X[4] f) {
- f[1].f1 = 102;
- f[1].f2 = true;
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm.function("get").call().unwrap();
- assert_eq!(
- returns,
- BorshToken::FixedArray(vec![
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 32,
- value: BigInt::zero(),
- },
- BorshToken::Bool(false)
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(102u8),
- },
- BorshToken::Bool(true)
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 32,
- value: BigInt::zero(),
- },
- BorshToken::Bool(false)
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 32,
- value: BigInt::zero(),
- },
- BorshToken::Bool(false)
- ]),
- ])
- );
- // Now let's try it the other way round; an struct with an array in it
- let mut vm = build_solidity(
- r#"
- struct X {
- bool f0;
- uint32[4] f1;
- bool f2;
- }
- contract foo {
- function get() public returns (X f) {
- f.f0 = true;
- f.f2 = true;
- }
- function set(X f) public returns (uint32) {
- assert(f.f0 == true);
- assert(f.f2 == true);
- uint32 sum = 0;
- for (uint32 i = 0; i < f.f1.length; i++) {
- sum += f.f1[i];
- }
- return sum;
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm.function("get").call().unwrap();
- assert_eq!(
- returns,
- BorshToken::Tuple(vec![
- BorshToken::Bool(true),
- BorshToken::FixedArray(vec![
- BorshToken::Uint {
- width: 32,
- value: BigInt::zero(),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::zero(),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::zero(),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::zero(),
- },
- ]),
- BorshToken::Bool(true)
- ]),
- );
- let returns = vm
- .function("set")
- .arguments(&[BorshToken::Tuple(vec![
- BorshToken::Bool(true),
- BorshToken::FixedArray(vec![
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(3u8),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(5u8),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(7u8),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(11u8),
- },
- ]),
- BorshToken::Bool(true),
- ])])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(26u8),
- }
- );
- }
- #[test]
- fn dynamic_array_fixed_elements() {
- // test that the abi decoder can handle fixed arrays
- let mut vm = build_solidity(
- r#"
- contract foo {
- function get(uint x, uint32[] f, uint g) public returns (uint32) {
- assert(x == 12123123);
- assert(g == 102);
- uint32 sum = 0;
- for (uint32 i = 0; i < f.length; i++) {
- sum += f[i];
- }
- return sum;
- }
- function set() public returns (uint x, uint32[] f, string g) {
- x = 12123123;
- f = new uint32[](4);
- f[0] = 3; f[1] = 5; f[2] = 7; f[3] = 11;
- g = "abcd";
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("get")
- .arguments(&[
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(12123123u32),
- },
- BorshToken::Array(vec![
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(3u8),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(5u8),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(7u8),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(11u8),
- },
- ]),
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(102u8),
- },
- ])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(26u8),
- }
- );
- // test that the abi encoder can handle fixed arrays
- let returns = vm.function("set").call().unwrap().unwrap_tuple();
- assert_eq!(
- returns,
- vec![
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(12123123u32),
- },
- BorshToken::Array(vec![
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(3u8),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(5u8),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(7u8),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(11u8),
- },
- ]),
- BorshToken::String(String::from("abcd")),
- ]
- );
- }
- #[test]
- fn fixed_array_dynamic_elements() {
- // test that the abi decoder can handle fixed arrays
- let mut vm = build_solidity(
- r#"
- contract foo {
- function get(uint x, bytes[4] f, uint g) public returns (uint32) {
- assert(x == 12123123);
- assert(g == 102);
- uint32 sum = 0;
- for (uint32 i = 0; i < f.length; i++) {
- for (uint32 j = 0; j < f[i].length; j++)
- sum += f[i][j];
- }
- return sum;
- }
- function set() public returns (uint x, bytes[4] f, uint g) {
- x = 12123123;
- f[0] = hex"030507";
- f[1] = hex"0b0d11";
- f[2] = hex"1317";
- f[3] = hex"1d";
- g = 102;
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("get")
- .arguments(&[
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(12123123u32),
- },
- BorshToken::FixedArray(vec![
- BorshToken::Bytes(vec![3, 5, 7]),
- BorshToken::Bytes(vec![11, 13, 17]),
- BorshToken::Bytes(vec![19, 23]),
- BorshToken::Bytes(vec![29]),
- ]),
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(102u8),
- },
- ])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(127),
- }
- );
- let returns = vm.function("set").call().unwrap().unwrap_tuple();
- assert_eq!(
- returns,
- vec![
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(12123123u32)
- },
- BorshToken::FixedArray(vec![
- BorshToken::Bytes(vec![3, 5, 7]),
- BorshToken::Bytes(vec![11, 13, 17]),
- BorshToken::Bytes(vec![19, 23]),
- BorshToken::Bytes(vec![29]),
- ]),
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(102u8)
- },
- ]
- );
- }
- #[test]
- fn dynamic_array_dynamic_elements() {
- // test that the abi decoder can handle fixed arrays
- let mut vm = build_solidity(
- r#"
- contract foo {
- function get(uint x, bytes[] f, uint g) public returns (uint32) {
- assert(x == 12123123);
- assert(g == 102);
- uint32 sum = 0;
- for (uint32 i = 0; i < f.length; i++) {
- for (uint32 j = 0; j < f[i].length; j++)
- sum += f[i][j];
- }
- return sum;
- }
- function set() public returns (uint x, bytes[] f, string g) {
- x = 12123123;
- f = new bytes[](4);
- f[0] = hex"030507";
- f[1] = hex"0b0d11";
- f[2] = hex"1317";
- f[3] = hex"1d";
- g = "feh";
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("get")
- .arguments(&[
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(12123123u32),
- },
- BorshToken::Array(vec![
- BorshToken::Bytes(vec![3, 5, 7]),
- BorshToken::Bytes(vec![11, 13, 17]),
- BorshToken::Bytes(vec![19, 23]),
- BorshToken::Bytes(vec![29]),
- ]),
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(102u8),
- },
- ])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(127),
- }
- );
- let returns = vm.function("set").call().unwrap().unwrap_tuple();
- assert_eq!(
- returns,
- vec![
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(12123123u32)
- },
- BorshToken::Array(vec![
- BorshToken::Bytes(vec![3, 5, 7]),
- BorshToken::Bytes(vec![11, 13, 17]),
- BorshToken::Bytes(vec![19, 23]),
- BorshToken::Bytes(vec![29]),
- ]),
- BorshToken::String(String::from("feh")),
- ]
- );
- }
- #[test]
- fn fixed_array_fixed_elements_storage() {
- let mut vm = build_solidity(
- r#"
- contract foo {
- int64[4] store;
- function set_elem(uint index, int64 val) public {
- store[index] = val;
- }
- function get_elem(uint index) public returns (int64) {
- return store[index];
- }
- function set(int64[4] x) public {
- store = x;
- }
- function get() public returns (int64[4]) {
- return store;
- }
- function del() public {
- delete store;
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("set_elem")
- .arguments(&[
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(2u8),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(12123123u64),
- },
- ])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("set_elem")
- .arguments(&[
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(3u8),
- },
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(123456789u64),
- },
- ])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("get_elem")
- .arguments(&[BorshToken::Uint {
- width: 256,
- value: BigInt::from(2u8),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Int {
- width: 64,
- value: BigInt::from(12123123u64)
- },
- );
- let returns = vm
- .function("get")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::FixedArray(vec![
- BorshToken::Int {
- width: 64,
- value: BigInt::zero()
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::zero()
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(12123123u32),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(123456789u32),
- },
- ]),
- );
- vm.function("set")
- .arguments(&[BorshToken::FixedArray(vec![
- BorshToken::Int {
- width: 64,
- value: BigInt::one(),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(2u8),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(3u8),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(4u8),
- },
- ])])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("get")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::FixedArray(vec![
- BorshToken::Int {
- width: 64,
- value: BigInt::one(),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(2u8),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(3u8),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(4u8),
- },
- ]),
- );
- vm.function("del")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("get")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::FixedArray(vec![
- BorshToken::Int {
- width: 64,
- value: BigInt::zero(),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::zero(),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::zero(),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::zero(),
- },
- ]),
- );
- }
- #[test]
- fn fixed_array_dynamic_elements_storage() {
- let mut vm = build_solidity(
- r#"
- contract foo {
- string[4] store;
- function set_elem(uint index, string val) public {
- store[index] = val;
- }
- function get_elem(uint index) public returns (string) {
- return store[index];
- }
- function set(string[4] x) public {
- store = x;
- }
- function get() public returns (string[4]) {
- return store;
- }
- function del() public {
- delete store;
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("set_elem")
- .arguments(&[
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(2u8),
- },
- BorshToken::String(String::from("abcd")),
- ])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("set_elem")
- .arguments(&[
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(3u8),
- },
- BorshToken::String(String::from(
- "you can lead a horse to water but you can’t make him drink",
- )),
- ])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("get_elem")
- .arguments(&[BorshToken::Uint {
- width: 256,
- value: BigInt::from(2u8),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(returns, BorshToken::String(String::from("abcd")));
- let returns = vm
- .function("get")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::FixedArray(vec![
- BorshToken::String(String::from("")),
- BorshToken::String(String::from("")),
- BorshToken::String(String::from("abcd")),
- BorshToken::String(String::from(
- "you can lead a horse to water but you can’t make him drink"
- )),
- ]),
- );
- vm.function("set")
- .arguments(&[BorshToken::FixedArray(vec![
- BorshToken::String(String::from("a")),
- BorshToken::String(String::from("b")),
- BorshToken::String(String::from("c")),
- BorshToken::String(String::from("d")),
- ])])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("get")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::FixedArray(vec![
- BorshToken::String(String::from("a")),
- BorshToken::String(String::from("b")),
- BorshToken::String(String::from("c")),
- BorshToken::String(String::from("d")),
- ]),
- );
- vm.function("del")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("get")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::FixedArray(vec![
- BorshToken::String(String::from("")),
- BorshToken::String(String::from("")),
- BorshToken::String(String::from("")),
- BorshToken::String(String::from("")),
- ]),
- );
- }
- #[test]
- fn storage_simple_dynamic_array() {
- let mut vm = build_solidity(
- r#"
- contract foo {
- int64[] store;
- function push(int64 x) public {
- store.push(x);
- }
- function push_zero() public {
- store.push();
- }
- function pop() public returns (int64) {
- return store.pop();
- }
- function len() public returns (uint) {
- return store.length;
- }
- function subscript(uint32 i) public returns (int64) {
- return store[i];
- }
- function copy() public returns (int64[] memory) {
- return store;
- }
- function set(int64[] n) public {
- store = n;
- }
- function rm() public {
- delete store;
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("len")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Uint {
- width: 256,
- value: BigInt::zero(),
- }
- );
- vm.function("push")
- .arguments(&[BorshToken::Int {
- width: 64,
- value: BigInt::from(102u8),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("push_zero")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("push")
- .arguments(&[BorshToken::Int {
- width: 64,
- value: BigInt::from(12345678901u64),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("subscript")
- .arguments(&[BorshToken::Uint {
- width: 32,
- value: BigInt::zero(),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Int {
- width: 64,
- value: BigInt::from(102u8),
- }
- );
- let returns = vm
- .function("subscript")
- .arguments(&[BorshToken::Uint {
- width: 32,
- value: BigInt::one(),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Int {
- width: 64,
- value: BigInt::zero()
- }
- );
- let returns = vm
- .function("subscript")
- .arguments(&[BorshToken::Uint {
- width: 32,
- value: BigInt::from(2u8),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Int {
- width: 64,
- value: BigInt::from(12345678901u64),
- },
- );
- let returns = vm
- .function("copy")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Array(vec![
- BorshToken::Int {
- width: 64,
- value: BigInt::from(102u8),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::zero(),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(12345678901u64),
- },
- ]),
- );
- let returns = vm
- .function("pop")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Int {
- width: 64,
- value: BigInt::from(12345678901u64),
- },
- );
- let returns = vm
- .function("len")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(2u8),
- }
- );
- vm.function("set")
- .arguments(&[BorshToken::Array(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(1u8),
- },
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(2u8),
- },
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(3u8),
- },
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(4u8),
- },
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(5u8),
- },
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(6u8),
- },
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(7u8),
- },
- ])])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("copy")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Array(vec![
- BorshToken::Int {
- width: 64,
- value: BigInt::from(1u8)
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(2u8)
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(3u8)
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(4u8)
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(5u8)
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(6u8)
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(7u8)
- },
- ]),
- );
- vm.function("rm")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("len")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Uint {
- width: 256,
- value: BigInt::zero(),
- }
- );
- }
- #[test]
- #[should_panic]
- fn storage_pop_running_on_empty() {
- let mut vm = build_solidity(
- r#"
- contract foo {
- int64[] store;
- function pop() public returns (int64) {
- return store.pop();
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("pop")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- }
- #[test]
- fn storage_dynamic_array_of_structs() {
- let mut vm = build_solidity(
- r#"
- struct S {
- uint64 f1;
- bool f2;
- }
- contract foo {
- S[] store;
- function push1(S x) public {
- store.push(x);
- }
- function push2(S x) public {
- S storage f = store.push();
- f.f1 = x.f1;
- f.f2 = x.f2;
- }
- function push_empty() public {
- store.push();
- }
- function pop() public returns (S) {
- return store.pop();
- }
- function len() public returns (uint) {
- return store.length;
- }
- function subscript(uint32 i) public returns (S) {
- return store[i];
- }
- function copy() public returns (S[] memory) {
- return store;
- }
- function set(S[] memory n) public {
- store = n;
- }
- function rm() public {
- delete store;
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("len")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Uint {
- width: 256,
- value: BigInt::zero(),
- }
- );
- vm.function("push1")
- .arguments(&[BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(13819038012u64),
- },
- BorshToken::Bool(true),
- ])])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("push_empty")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("push2")
- .arguments(&[BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(12313123141123213u64),
- },
- BorshToken::Bool(true),
- ])])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("subscript")
- .arguments(&[BorshToken::Uint {
- width: 32,
- value: BigInt::zero(),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(13819038012u64)
- },
- BorshToken::Bool(true),
- ])
- );
- let returns = vm
- .function("subscript")
- .arguments(&[BorshToken::Uint {
- width: 32,
- value: BigInt::one(),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::zero(),
- },
- BorshToken::Bool(false),
- ])
- );
- let returns = vm
- .function("subscript")
- .arguments(&[BorshToken::Uint {
- width: 32,
- value: BigInt::from(2u8),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(12313123141123213u64),
- },
- BorshToken::Bool(true),
- ]),
- );
- let returns = vm
- .function("copy")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Array(vec![
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(13819038012u64)
- },
- BorshToken::Bool(true),
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::zero(),
- },
- BorshToken::Bool(false),
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(12313123141123213u64),
- },
- BorshToken::Bool(true),
- ]),
- ])
- );
- let returns = vm
- .function("pop")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(12313123141123213u64),
- },
- BorshToken::Bool(true),
- ])
- );
- let returns = vm
- .function("len")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Uint {
- width: 256,
- value: BigInt::from(2u8),
- }
- );
- vm.function("set")
- .arguments(&[BorshToken::Array(vec![
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::one(),
- },
- BorshToken::Bool(false),
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(2u8),
- },
- BorshToken::Bool(true),
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(3u8),
- },
- BorshToken::Bool(false),
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(4u8),
- },
- BorshToken::Bool(true),
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(5u8),
- },
- BorshToken::Bool(false),
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(6u8),
- },
- BorshToken::Bool(true),
- ]),
- ])])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("copy")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Array(vec![
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::one(),
- },
- BorshToken::Bool(false)
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(2u8),
- },
- BorshToken::Bool(true)
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(3u8),
- },
- BorshToken::Bool(false)
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(4u8),
- },
- BorshToken::Bool(true)
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(5u8),
- },
- BorshToken::Bool(false)
- ]),
- BorshToken::Tuple(vec![
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(6u8),
- },
- BorshToken::Bool(true)
- ]),
- ]),
- );
- vm.function("rm")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("len")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::Uint {
- width: 256,
- value: BigInt::zero(),
- }
- );
- }
- #[test]
- fn array_literal() {
- let mut vm = build_solidity(
- r#"
- contract foo {
- int64 constant foo = 1;
- int64 bar = 2;
- function list() public returns (int64[3]) {
- return [foo, bar, 3];
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("list")
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::FixedArray(vec![
- BorshToken::Int {
- width: 64,
- value: BigInt::one(),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(2u8),
- },
- BorshToken::Int {
- width: 64,
- value: BigInt::from(3u8),
- },
- ])
- );
- }
- #[test]
- fn storage_pop_push() {
- let mut vm = build_solidity(
- r#"
- contract Testing {
- struct NonConstantStruct {
- string[] b;
- }
- string[] vec_2;
- NonConstantStruct[] public complex_array;
- function fn1() public {
- vec_2.push("tea");
- }
- function fn2() public {
- vec_2.push("coffee");
- }
- function fn3() public {
- NonConstantStruct memory ss = NonConstantStruct(vec_2);
- complex_array.push(ss);
- }
- function fn4() public {
- vec_2.pop();
- }
- function fn5() public {
- vec_2.pop();
- }
- function fn6() public {
- vec_2.push("cortado");
- }
- function fn7() public {
- vec_2.push("cappuccino");
- }
- function fn8() public {
- NonConstantStruct memory sr = NonConstantStruct(vec_2);
- complex_array.push(sr);
- }
- function clear() public {
- vec_2 = new string[](0);
- complex_array = new NonConstantStruct[](0);
- }
- }"#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("fn1")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("fn2")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("fn3")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("fn4")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("fn5")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("fn6")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("fn7")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("fn8")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- vm.function("clear")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- // make sure every thing has been freed
- assert_eq!(vm.validate_account_data_heap(&Pubkey(data_account)), 0);
- }
- #[test]
- fn initialization_with_literal() {
- let mut vm = build_solidity(
- r#"
- contract Testing {
- address[] splitAddresses;
- function split(address addr1, address addr2) public {
- splitAddresses = [addr1, addr2];
- }
- function getIdx(uint32 idx) public view returns (address) {
- return splitAddresses[idx];
- }
- function getVec(uint32 a, uint32 b) public pure returns (uint32[] memory) {
- uint32[] memory vec;
- vec = [a, b];
- return vec;
- }
- }
- "#,
- );
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let mut addr1: Vec<u8> = vec![0; 32];
- addr1[0] = 1;
- let mut addr2: Vec<u8> = vec![0; 32];
- addr2[0] = 2;
- let _ = vm
- .function("split")
- .arguments(&[
- BorshToken::FixedBytes(addr1[..].to_vec()),
- BorshToken::FixedBytes(addr2[..].to_vec()),
- ])
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let returns = vm
- .function("getIdx")
- .arguments(&[BorshToken::Uint {
- width: 32,
- value: BigInt::zero(),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- let returned_addr1 = returns.into_fixed_bytes().unwrap();
- assert_eq!(addr1, returned_addr1);
- let returns = vm
- .function("getIdx")
- .arguments(&[BorshToken::Uint {
- width: 32,
- value: BigInt::one(),
- }])
- .accounts(vec![("dataAccount", data_account)])
- .call()
- .unwrap();
- let returned_addr2 = returns.into_fixed_bytes().unwrap();
- assert_eq!(addr2, returned_addr2);
- let returns = vm
- .function("getVec")
- .arguments(&[
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(563u16),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(895u16),
- },
- ])
- .call()
- .unwrap();
- let array = returns.into_array().unwrap();
- assert_eq!(
- array,
- vec![
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(563u16),
- },
- BorshToken::Uint {
- width: 32,
- value: BigInt::from(895u16),
- },
- ]
- );
- }
- #[test]
- fn dynamic_array_push() {
- let mut runtime = build_solidity(
- r#"
- pragma solidity 0;
- contract foo {
- function test() public {
- int[] bar = (new int[])(1);
- bar[0] = 128;
- bar.push(64);
- assert(bar.length == 2);
- assert(bar[1] == 64);
- }
- }
- "#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime.function("test").call();
- let mut runtime = build_solidity(
- r#"
- pragma solidity 0;
- contract foo {
- function test() public {
- bytes bar = (new bytes)(1);
- bar[0] = 128;
- bar.push(64);
- assert(bar.length == 2);
- assert(bar[1] == 64);
- }
- }
- "#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime.function("test").call();
- let mut runtime = build_solidity(
- r#"
- pragma solidity 0;
- contract foo {
- struct s {
- int32 f1;
- bool f2;
- }
- function test() public {
- s[] bar = new s[](1);
- bar[0] = s({f1: 0, f2: false});
- bar.push(s({f1: 1, f2: true}));
- assert(bar.length == 2);
- assert(bar[1].f1 == 1);
- assert(bar[1].f2 == true);
- }
- }
- "#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime.function("test").call();
- let mut runtime = build_solidity(
- r#"
- pragma solidity 0;
- contract foo {
- enum enum1 { val1, val2, val3 }
- function test() public {
- enum1[] bar = new enum1[](1);
- bar[0] = enum1.val1;
- bar.push(enum1.val2);
- assert(bar.length == 2);
- assert(bar[1] == enum1.val2);
- }
- }
- "#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime.function("test").call();
- // push() returns a reference to the thing
- let mut runtime = build_solidity(
- r#"
- pragma solidity 0;
- contract foo {
- struct s {
- int32 f1;
- bool f2;
- }
- function test() public {
- s[] bar = new s[](0);
- s memory n = bar.push();
- n.f1 = 102;
- n.f2 = true;
- assert(bar[0].f1 == 102);
- assert(bar[0].f2 == true);
- }
- }"#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime.function("test").call();
- }
- #[test]
- fn dynamic_array_pop() {
- let mut runtime = build_solidity(
- r#"
- pragma solidity 0;
- contract foo {
- function test() public {
- int[] bar = new int[](1);
- bar[0] = 128;
- assert(bar.length == 1);
- assert(128 == bar.pop());
- assert(bar.length == 0);
- }
- }
- "#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime.function("test").call();
- let mut runtime = build_solidity(
- r#"
- pragma solidity 0;
- contract foo {
- function test() public {
- bytes bar = new bytes(1);
- bar[0] = 128;
- assert(bar.length == 1);
- assert(128 == bar.pop());
- assert(bar.length == 0);
- }
- }
- "#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime.function("test").call();
- let mut runtime = build_solidity(
- r#"
- pragma solidity 0;
- contract foo {
- struct s {
- int32 f1;
- bool f2;
- }
- function test() public {
- s[] bar = new s[](1);
- bar[0] = s(128, true);
- assert(bar.length == 1);
- s baz = bar.pop();
- assert(baz.f1 == 128);
- assert(baz.f2 == true);
- assert(bar.length == 0);
- }
- }
- "#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime.function("test").call();
- let mut runtime = build_solidity(
- r#"
- pragma solidity 0;
- contract foo {
- enum enum1 { val1, val2, val3 }
- function test() public {
- enum1[] bar = new enum1[](1);
- bar[0] = enum1.val2;
- assert(bar.length == 1);
- assert(enum1.val2 == bar.pop());
- assert(bar.length == 0);
- }
- }
- "#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime.function("test").call();
- }
- #[test]
- #[should_panic]
- fn dynamic_array_pop_empty_array() {
- let mut runtime = build_solidity(
- r#"
- pragma solidity 0;
- contract foo {
- function test() public returns (int) {
- int[] bar = new int[](0);
- return bar.pop();
- }
- }"#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime
- .function("test")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- }
- #[test]
- #[should_panic]
- fn dynamic_array_pop_bounds() {
- let mut runtime = build_solidity(
- r#"
- pragma solidity 0;
- contract foo {
- function test() public {
- int[] bar = new int[](1);
- bar[0] = 12;
- bar.pop();
- assert(bar[0] == 12);
- }
- }"#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime
- .function("test")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- }
- #[test]
- fn dynamic_array_push_pop_loop() {
- let mut runtime = build_solidity(
- r#"
- contract foo {
- function test() public {
- uint32[] bar1 = new uint32[](0);
- uint32[] bar2 = new uint32[](0);
- // each time we call a system call, the heap is checked
- // for consistency. So do a print() after each operation
- for (uint64 i = 1; i < 160; i++) {
- if ((i % 10) == 0) {
- bar1.pop();
- print("bar1.pop");
- bar2.pop();
- print("bar2.pop");
- } else {
- uint32 v = bar1.length;
- bar1.push(v);
- print("bar1.push");
- bar2.push(v);
- print("bar2.push");
- }
- }
- assert(bar1.length == bar2.length);
- for (uint32 i = 0; i < bar1.length; i++) {
- assert(bar1[i] == i);
- assert(bar2[i] == i);
- }
- }
- }"#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime.function("test").call();
- let mut runtime = build_solidity(
- r#"
- contract foo {
- function test() public {
- bytes bar1 = new bytes(0);
- bytes bar2 = new bytes(0);
- // each time we call a system call, the heap is checked
- // for consistency. So do a print() after each operation
- for (uint64 i = 1; i < 160; i++) {
- if ((i % 10) == 0) {
- bar1.pop();
- print("bar1.pop");
- bar2.pop();
- print("bar2.pop");
- } else {
- uint8 v = uint8(bar1.length);
- bar1.push(v);
- print("bar1.push");
- bar2.push(v);
- print("bar2.push");
- }
- }
- assert(bar1.length == bar2.length);
- for (uint32 i = 0; i < bar1.length; i++) {
- uint8 v = uint8(i);
- print("{}.{}.{}".format(v, bar1[i], bar2[i]));
- assert(bar1[i] == v);
- assert(bar2[i] == v);
- }
- }
- }"#,
- );
- let data_account = runtime.initialize_data_account();
- runtime
- .function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- runtime.function("test").call();
- }
- #[test]
- fn double_index() {
- let src = r#"
- contract RH {
- function calc(uint256[] memory separators, int256[] memory params) public pure returns (int256[4] memory) {
- int256 stopLimit = params[separators[4]];
- int256 contractedValueRatio = params[separators[6]];
- return [stopLimit, contractedValueRatio, 3, 4];
- }
- }
- "#;
- let mut vm = build_solidity(src);
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let separators = BorshToken::Array(vec![
- BorshToken::Int {
- width: 256,
- value: BigInt::from(25u8),
- },
- BorshToken::Int {
- width: 256,
- value: BigInt::from(25u8),
- },
- BorshToken::Int {
- width: 256,
- value: BigInt::from(25u8),
- },
- BorshToken::Int {
- width: 256,
- value: BigInt::from(25u8),
- },
- BorshToken::Int {
- width: 256,
- value: BigInt::from(1u8),
- },
- BorshToken::Int {
- width: 256,
- value: BigInt::from(25u8),
- },
- BorshToken::Int {
- width: 256,
- value: BigInt::from(0u8),
- },
- ]);
- let params = BorshToken::Array(vec![
- BorshToken::Int {
- width: 256,
- value: BigInt::from(80u8),
- },
- BorshToken::Int {
- width: 256,
- value: BigInt::from(98u8),
- },
- ]);
- let returns = vm
- .function("calc")
- .arguments(&[separators, params])
- .call()
- .unwrap();
- assert_eq!(
- returns,
- BorshToken::FixedArray(vec![
- BorshToken::Int {
- width: 256,
- value: BigInt::from(98u8),
- },
- BorshToken::Int {
- width: 256,
- value: BigInt::from(80u8),
- },
- BorshToken::Int {
- width: 256,
- value: BigInt::from(3u8),
- },
- BorshToken::Int {
- width: 256,
- value: BigInt::from(4u8),
- },
- ])
- );
- }
- #[test]
- fn push_empty_array() {
- let src = r#"
- contract MyTest {
- function foo() public pure returns (bytes memory) {
- bytes b1 = hex"41";
- bytes b2 = hex"41";
- b2.push(0x41);
- return (b1);
- }
- function foo2() public pure returns (uint64) {
- uint64[] a;
- a.push(20);
- return a[0];
- }
- }
- "#;
- let mut vm = build_solidity(src);
- let data_account = vm.initialize_data_account();
- vm.function("new")
- .accounts(vec![("dataAccount", data_account)])
- .call();
- let ret = vm.function("foo").call().unwrap();
- assert_eq!(ret, BorshToken::Bytes(vec![65]));
- let ret = vm.function("foo2").call().unwrap();
- assert_eq!(
- ret,
- BorshToken::Uint {
- width: 64,
- value: BigInt::from(20),
- }
- );
- }
|