浏览代码

Emitting events causes runtime failures on Solana

self.abi_encode() does not work for encoding events. Events are not
supported, so ignore them for now.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 年之前
父节点
当前提交
c15d2b0fe7
共有 3 个文件被更改,包括 108 次插入33 次删除
  1. 36 0
      integration/solana/oznfc.sol
  2. 36 0
      integration/solana/oznfc.spec.ts
  3. 36 33
      src/codegen/statements.rs

+ 36 - 0
integration/solana/oznfc.sol

@@ -0,0 +1,36 @@
+contract Events {
+    string public name;
+    string public surname;
+
+    event NameChanced(string message, string newName);
+    event SurnameChanced(string message, string newSurname);
+
+    constructor() public {
+        name = 'myName';
+        surname = 'mySurname';
+    }
+
+    function setName(string memory _name) public {
+        name = _name;
+        emit NameChanced('Name Chanced', 'x');
+    }
+
+    function setSurname(string memory _surname) public {
+        surname = _surname;
+        emit SurnameChanced('Surname Chanced', _surname);
+    }
+
+    function getNames() public view returns (string memory _name , string memory _surname ) {
+        return (name ,surname);
+    }
+
+
+    function getName() public view returns (string memory _name ) {
+        return name ;
+    }
+
+     function getSurname() public view returns (string memory _surname ) {
+        return surname ;
+    }
+
+}

+ 36 - 0
integration/solana/oznfc.spec.ts

@@ -0,0 +1,36 @@
+import expect from 'expect';
+import { establishConnection } from './index';
+
+describe('Deploy solang contract and test', () => {
+    it('Events', async function () {
+        this.timeout(50000);
+
+        let conn = await establishConnection();
+
+        let hash_functions = await conn.loadProgram("bundle.so", "Events.abi");
+
+        // call the constructor
+        await hash_functions.call_constructor(conn, 'Events', []);
+
+        let res = await hash_functions.call_function(conn, "getName", []);
+
+        expect(res["0"]).toBe("myName");
+
+        await hash_functions.call_function(conn, "setName", ['ozan']);
+
+        res = await hash_functions.call_function(conn, "getName", []);
+
+        expect(res["0"]).toBe('ozan');
+
+        await hash_functions.call_function(conn, "setSurname", ['martin']);
+
+        res = await hash_functions.call_function(conn, "getSurname", []);
+
+        expect(res["0"]).toBe('martin');
+
+        res = await hash_functions.call_function(conn, "getNames", []);
+
+        expect(res["0"]).toBe('ozan');
+        expect(res["1"]).toBe('martin');
+    });
+});

+ 36 - 33
src/codegen/statements.rs

@@ -508,43 +508,46 @@ pub fn statement(
             return_override,
         ),
         Statement::Emit { event_no, args, .. } => {
-            let event = &ns.events[*event_no];
-            let mut data = Vec::new();
-            let mut data_tys = Vec::new();
-            let mut topics = Vec::new();
-            let mut topic_tys = Vec::new();
-
-            for (i, arg) in args.iter().enumerate() {
-                let param = Parameter {
-                    ty: arg.ty(),
-                    ty_loc: arg.loc(),
-                    loc: arg.loc(),
-                    name: "".to_owned(),
-                    name_loc: None,
-                    indexed: false,
-                };
+            // Solana cannot emit events, and breaks when the emitter calls self.abi_encode()
+            if ns.target != crate::Target::Solana {
+                let event = &ns.events[*event_no];
+                let mut data = Vec::new();
+                let mut data_tys = Vec::new();
+                let mut topics = Vec::new();
+                let mut topic_tys = Vec::new();
+
+                for (i, arg) in args.iter().enumerate() {
+                    let param = Parameter {
+                        ty: arg.ty(),
+                        ty_loc: arg.loc(),
+                        loc: arg.loc(),
+                        name: "".to_owned(),
+                        name_loc: None,
+                        indexed: false,
+                    };
 
-                let e = expression(arg, cfg, contract_no, Some(func), ns, vartab);
+                    let e = expression(arg, cfg, contract_no, Some(func), ns, vartab);
 
-                if event.fields[i].indexed {
-                    topics.push(e);
-                    topic_tys.push(param);
-                } else {
-                    data.push(e);
-                    data_tys.push(param);
+                    if event.fields[i].indexed {
+                        topics.push(e);
+                        topic_tys.push(param);
+                    } else {
+                        data.push(e);
+                        data_tys.push(param);
+                    }
                 }
-            }
 
-            cfg.add(
-                vartab,
-                Instr::EmitEvent {
-                    event_no: *event_no,
-                    data,
-                    data_tys,
-                    topics,
-                    topic_tys,
-                },
-            );
+                cfg.add(
+                    vartab,
+                    Instr::EmitEvent {
+                        event_no: *event_no,
+                        data,
+                        data_tys,
+                        topics,
+                        topic_tys,
+                    },
+                );
+            }
         }
         Statement::Underscore(_) => {
             cfg.add(