浏览代码

Pushing onto two different arrays causes many reallocations

This fixes an issue raised on discord:

https://discord.com/channels/905194001349627914/905834552965103638/949343674272219226

On Solana, contract storage in storage in account data which is a
continious piece of memory. In order to support growable objects like
dynamic arrays, we have a mini heap implementation. This fixes a problem
in the realloc implementation.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 3 年之前
父节点
当前提交
7d03fffdd4
共有 4 个文件被更改,包括 22 次插入1 次删除
  1. 二进制
      stdlib/bpf/solana.bc
  2. 1 1
      stdlib/solana.c
  3. 1 0
      tests/solana.rs
  4. 20 0
      tests/solana_tests/simple.rs

二进制
stdlib/bpf/solana.bc


+ 1 - 1
stdlib/solana.c

@@ -839,7 +839,7 @@ uint64_t account_data_realloc(SolAccountInfo *ai, uint32_t offset, uint32_t size
         return rc;
 
     __memcpy(data + new_offset, data + offset, old_length);
-    account_data_free(ai, offset);
+    account_data_free(data, offset);
 
     *res = new_offset;
     return 0;

+ 1 - 0
tests/solana.rs

@@ -1300,6 +1300,7 @@ impl VirtualMachine {
         };
 
         let res = self.execute(&calldata, &[]);
+        println!("res:{:?}", res);
         assert!(matches!(res, Ok(0)));
     }
 

+ 20 - 0
tests/solana_tests/simple.rs

@@ -260,3 +260,23 @@ contract line {
         "implicit conversion from int to address not allowed"
     );
 }
+
+#[test]
+fn two_arrays() {
+    let mut vm = build_solidity(
+        r#"
+        contract two_arrays {
+            uint[] array1;
+            uint[] array2;
+
+            constructor() {
+                for(uint i = 0; i < 10; i++) {
+                    array1.push((i*uint(sha256("i"))));
+                    array2.push(((i+1)*uint(sha256("i"))));
+               }
+            }
+        }"#,
+    );
+
+    vm.constructor("two_arrays", &[], 0);
+}