mappings.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. // SPDX-License-Identifier: Apache-2.0
  2. use parity_scale_codec::{Decode, Encode};
  3. use rand::Rng;
  4. use std::collections::HashMap;
  5. use crate::build_solidity;
  6. #[test]
  7. fn basic() {
  8. let mut runtime = build_solidity(
  9. r##"
  10. contract c {
  11. mapping(uint => bytes4) data;
  12. function test() public {
  13. data[1] = hex"cafedead";
  14. assert(data[1] == hex"cafedead");
  15. }
  16. }
  17. "##,
  18. );
  19. runtime.function("test", Vec::new());
  20. let mut runtime = build_solidity(
  21. r##"
  22. contract Test {
  23. using TestLib for TestLib.data;
  24. TestLib.data libdata;
  25. function contfunc(uint64 num) public {
  26. libdata.libfunc(num);
  27. }
  28. }
  29. library TestLib {
  30. using TestLib for TestLib.data;
  31. struct pair {
  32. uint64 a;
  33. uint64 b;
  34. }
  35. struct data {
  36. mapping(uint64 => pair) pairmap;
  37. }
  38. function libfunc(data storage self, uint64 value) internal {
  39. self.pairmap[self.pairmap[value].a].a = 1;
  40. self.pairmap[self.pairmap[value].b].b = 2;
  41. }
  42. }
  43. "##,
  44. );
  45. runtime.constructor(0, Vec::new());
  46. runtime.function("contfunc", 1u64.encode());
  47. }
  48. #[test]
  49. fn test_uint64() {
  50. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  51. struct Val(i32);
  52. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  53. struct SetArg(u64, i32);
  54. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  55. struct GetArg(u64);
  56. let mut runtime = build_solidity(
  57. r##"
  58. contract foo {
  59. mapping(uint64 => int32) v;
  60. function set(uint64 index, int32 val) public {
  61. v[index] = val;
  62. }
  63. function get(uint64 index) public returns (int32) {
  64. return v[index];
  65. }
  66. }"##,
  67. );
  68. let mut rng = rand::thread_rng();
  69. let mut vals = Vec::new();
  70. for _ in 0..100 {
  71. let index = rng.gen::<u64>();
  72. let val = rng.gen::<i32>();
  73. runtime.function("set", SetArg(index, val).encode());
  74. vals.push((index, val));
  75. }
  76. for val in vals {
  77. runtime.function("get", GetArg(val.0).encode());
  78. assert_eq!(runtime.output(), Val(val.1).encode());
  79. }
  80. }
  81. #[test]
  82. fn test_enum() {
  83. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  84. struct Val(i32);
  85. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  86. struct SetArg(u8, i32);
  87. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  88. struct GetArg(u8);
  89. let mut runtime = build_solidity(
  90. r##"
  91. contract foo {
  92. enum bar { bar1,bar2,bar3,bar4,bar5,bar6,bar7,bar8,bar9,bar10,bar11,bar12,bar13,bar14,bar15,bar16,bar17,bar18,bar19,bar20,bar21,bar22,bar23,bar24,bar25,bar26,bar27,bar28,bar29,bar30,bar31,bar32,bar33,bar34,bar35,bar36,bar37,bar38,bar39,bar40,bar41,bar42,bar43,bar44,bar45,bar46,bar47,bar48,bar49,bar50,bar51,bar52,bar53,bar54,bar55,bar56,bar57,bar58,bar59,bar60,bar61,bar62,bar63,bar64,bar65,bar66,bar67,bar68,bar69,bar70,bar71,bar72,bar73,bar74,bar75,bar76,bar77,bar78,bar79,bar80,bar81,bar82,bar83,bar84,bar85,bar86,bar87,bar88,bar89,bar90,bar91,bar92,bar93,bar94,bar95,bar96,bar97,bar98,bar99,bar100}
  93. mapping(bar => int32) v;
  94. function set(bar index, int32 val) public {
  95. v[index] = val;
  96. }
  97. function get(bar index) public returns (int32) {
  98. return v[index];
  99. }
  100. }"##,
  101. );
  102. let mut rng = rand::thread_rng();
  103. let mut vals = HashMap::new();
  104. for _ in 0..100 {
  105. let index = rng.gen::<u8>() % 100;
  106. let val = rng.gen::<i32>();
  107. runtime.function("set", SetArg(index, val).encode());
  108. vals.insert(index, val);
  109. }
  110. for val in vals {
  111. runtime.function("get", GetArg(val.0).encode());
  112. assert_eq!(runtime.output(), Val(val.1).encode());
  113. }
  114. }
  115. #[test]
  116. fn test_string() {
  117. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  118. struct Val(i64);
  119. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  120. struct SetArg(Vec<u8>, i64);
  121. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  122. struct GetArg(Vec<u8>);
  123. let mut runtime = build_solidity(
  124. r##"
  125. contract foo {
  126. mapping(bytes => int64) v;
  127. function set(bytes index, int64 val) public {
  128. v[index] = val;
  129. }
  130. function get(bytes index) public returns (int64) {
  131. return v[index];
  132. }
  133. }"##,
  134. );
  135. let mut rng = rand::thread_rng();
  136. let mut vals = HashMap::new();
  137. for _ in 0..100 {
  138. let len = rng.gen::<usize>() % 256;
  139. let mut index = Vec::new();
  140. index.resize(len, 0u8);
  141. rng.fill(&mut index[..]);
  142. let val = rng.gen::<i64>();
  143. runtime.function("set", SetArg(index.clone(), val).encode());
  144. vals.insert(index, val);
  145. }
  146. for val in vals {
  147. runtime.function("get", GetArg(val.0).encode());
  148. assert_eq!(runtime.output(), Val(val.1).encode());
  149. }
  150. }
  151. #[test]
  152. fn test_user() {
  153. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  154. struct AddArg(Vec<u8>, [u8; 32]);
  155. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  156. struct GetArg(Vec<u8>);
  157. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  158. struct GetRet(bool, [u8; 32]);
  159. let mut runtime = build_solidity(
  160. r##"
  161. contract b {
  162. struct user {
  163. bool exists;
  164. address addr;
  165. }
  166. mapping(string => user) users;
  167. function add(string name, address addr) public {
  168. // assigning to a storage variable creates a reference
  169. user storage s = users[name];
  170. s.exists = true;
  171. s.addr = addr;
  172. }
  173. function get(string name) public view returns (bool, address) {
  174. // assigning to a memory variable creates a copy
  175. user s = users[name];
  176. return (s.exists, s.addr);
  177. }
  178. function rm(string name) public {
  179. delete users[name];
  180. }
  181. function get_foo() public view returns (bool, address) {
  182. user storage s = users["foo"];
  183. return (s.exists, s.addr);
  184. }
  185. }"##,
  186. );
  187. let mut rng = rand::thread_rng();
  188. let mut vals = HashMap::new();
  189. for _ in 0..100 {
  190. let len = rng.gen::<usize>() % 256;
  191. let mut index = Vec::new();
  192. index.resize(len, 0u8);
  193. rng.fill(&mut index[..]);
  194. let mut val = [0u8; 32];
  195. rng.fill(&mut val[..]);
  196. runtime.function("add", AddArg(index.clone(), val).encode());
  197. vals.insert(index, val);
  198. }
  199. for val in &vals {
  200. runtime.function("get", GetArg(val.0.clone()).encode());
  201. assert_eq!(runtime.output(), GetRet(true, *val.1).encode());
  202. }
  203. // now delete them
  204. for val in &vals {
  205. runtime.function("rm", GetArg(val.0.clone()).encode());
  206. }
  207. for val in vals {
  208. runtime.function("get", GetArg(val.0).encode());
  209. assert_eq!(runtime.output(), GetRet(false, [0u8; 32]).encode());
  210. }
  211. runtime.function("add", AddArg(b"foo".to_vec(), [1u8; 32]).encode());
  212. runtime.function("get_foo", Vec::new());
  213. assert_eq!(runtime.output(), GetRet(true, [1u8; 32]).encode());
  214. }
  215. #[test]
  216. fn test_string_map() {
  217. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  218. struct AddArg([u8; 32], Vec<u8>);
  219. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  220. struct GetArg([u8; 32]);
  221. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  222. struct GetRet(Vec<u8>);
  223. let mut runtime = build_solidity(
  224. r##"
  225. contract b {
  226. struct SendTo{
  227. address sender;
  228. bytes hexOfAsset;
  229. bool paid;
  230. }
  231. mapping(address => SendTo) send;
  232. function add(address a, bytes v) public {
  233. send[a].hexOfAsset = v;
  234. }
  235. function get(address a) public view returns (bytes) {
  236. return send[a].hexOfAsset;
  237. }
  238. function rm(address a) public {
  239. delete send[a].hexOfAsset;
  240. }
  241. }"##,
  242. );
  243. let mut rng = rand::thread_rng();
  244. let mut vals = HashMap::new();
  245. for _ in 0..10 {
  246. let len = rng.gen::<usize>() % 256;
  247. let mut val = Vec::new();
  248. val.resize(len, 0u8);
  249. rng.fill(&mut val[..]);
  250. let mut address = [0u8; 32];
  251. rng.fill(&mut address[..]);
  252. runtime.function("add", AddArg(address, val.clone()).encode());
  253. vals.insert(address, val);
  254. }
  255. for (address, val) in &vals {
  256. runtime.function("get", GetArg(*address).encode());
  257. assert_eq!(runtime.output(), GetRet(val.clone()).encode());
  258. }
  259. // now delete them
  260. for address in vals.keys() {
  261. runtime.function("rm", GetArg(*address).encode());
  262. }
  263. for address in vals.keys() {
  264. runtime.function("get", GetArg(*address).encode());
  265. assert_eq!(runtime.output(), GetRet(Vec::new()).encode());
  266. }
  267. }
  268. #[test]
  269. fn test_address() {
  270. type Address = [u8; 32];
  271. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  272. struct Val(i64);
  273. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  274. struct SetArg(Address, i64);
  275. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  276. struct GetArg(Address);
  277. let mut runtime = build_solidity(
  278. r##"
  279. contract foo {
  280. uint bvar1;
  281. uint bvar2;
  282. mapping(address => int64) v;
  283. function set(address index, int64 val) public {
  284. v[index] = val;
  285. }
  286. function get(address index) public returns (int64) {
  287. return v[index];
  288. }
  289. }"##,
  290. );
  291. let mut rng = rand::thread_rng();
  292. let mut vals = HashMap::new();
  293. let mut index: Address = [0u8; 32];
  294. for _ in 0..100 {
  295. rng.fill(&mut index[..]);
  296. let val = rng.gen::<i64>();
  297. runtime.function("set", SetArg(index, val).encode());
  298. vals.insert(index, val);
  299. }
  300. for val in vals {
  301. runtime.function("get", GetArg(val.0).encode());
  302. assert_eq!(runtime.output(), Val(val.1).encode());
  303. }
  304. }