Selaa lähdekoodia

Polkadot: Bugfix codegen for empty events (#1637)

Slight oversight from #1632: Previously, events always contained at least a
single byte of data (empty events would have the discriminant/index of
the event enum). However now, the data field for empty events is
actually empty, leading the ABI encoder to panic. So in codegen we check if we
have to encode data first and pass a pointer to an empty buffer if not.
Cyrill Leutwiler 1 vuosi sitten
vanhempi
sitoutus
05a67069f7

+ 4 - 0
integration/polkadot/events.sol

@@ -10,6 +10,8 @@ contract Events {
     event ThisEventTopicShouldGetHashed(address indexed caller);
     event ThisEventTopicShouldGetHashed(address indexed caller);
     event Event(bool indexed something);
     event Event(bool indexed something);
 
 
+    event Empty();
+
     function emit_event() public {
     function emit_event() public {
         emit foo1(254, "hello there");
         emit foo1(254, "hello there");
 
 
@@ -18,5 +20,7 @@ contract Events {
         emit ThisEventTopicShouldGetHashed(msg.sender);
         emit ThisEventTopicShouldGetHashed(msg.sender);
 
 
         emit Event(true);
         emit Event(true);
+
+        emit Empty();
     }
     }
 }
 }

+ 8 - 1
integration/polkadot/events.spec.ts

@@ -29,7 +29,7 @@ describe('Deploy events contract and test event data, docs and topics', () => {
         let res0: any = await transaction(tx, alice);
         let res0: any = await transaction(tx, alice);
         let events: DecodedEvent[] = res0.contractEvents;
         let events: DecodedEvent[] = res0.contractEvents;
 
 
-        expect(events.length).toEqual(4);
+        expect(events.length).toEqual(5);
 
 
         expect(events[0].event.identifier).toBe("Events::foo1");
         expect(events[0].event.identifier).toBe("Events::foo1");
         expect(events[0].event.docs).toEqual(["Ladida tada"]);
         expect(events[0].event.docs).toEqual(["Ladida tada"]);
@@ -63,5 +63,12 @@ describe('Deploy events contract and test event data, docs and topics', () => {
         expect(field_topic.length).toBe(1);
         expect(field_topic.length).toBe(1);
         event_topic = await conn.query.system.eventTopics("0xc2bc7a077121efada8bc6a0af16c1e886406e8c2d1716979cb1b92098d8b49bc");
         event_topic = await conn.query.system.eventTopics("0xc2bc7a077121efada8bc6a0af16c1e886406e8c2d1716979cb1b92098d8b49bc");
         expect(event_topic.length).toBe(1);
         expect(event_topic.length).toBe(1);
+
+        // The 5th event yields no data and the following event topic:
+        // - blake2x256 sum of its signature: 'Empty()'
+
+        event_topic = await conn.query.system.eventTopics("0x2c54a2a9a9aa474af5d6e2bb2e5a35b84051acaf95b233f98f96860d36f2b81b");
+        expect(event_topic.length).toBe(1);
+        expect(events[4].args.map(a => a.toJSON())).toEqual([]);
     });
     });
 });
 });

+ 15 - 2
src/codegen/events/polkadot.rs

@@ -147,8 +147,21 @@ impl EventEmitter for PolkadotEventEmitter<'_> {
             .args
             .args
             .iter()
             .iter()
             .map(|e| expression(e, cfg, contract_no, Some(func), self.ns, vartab, opt))
             .map(|e| expression(e, cfg, contract_no, Some(func), self.ns, vartab, opt))
-            .collect();
-        let encoded_data = abi_encode(&loc, data, self.ns, vartab, cfg, false).0;
+            .collect::<Vec<_>>();
+        let encoded_data = data
+            .is_empty()
+            .then(|| Expression::AllocDynamicBytes {
+                loc,
+                ty: Type::DynamicBytes,
+                size: Expression::NumberLiteral {
+                    loc,
+                    ty: Type::Uint(32),
+                    value: 0.into(),
+                }
+                .into(),
+                initializer: Vec::new().into(),
+            })
+            .unwrap_or_else(|| abi_encode(&loc, data, self.ns, vartab, cfg, false).0);
 
 
         cfg.add(
         cfg.add(
             vartab,
             vartab,