Fuel merge part 3 - Start working on EventMod codegen - #150
Conversation
|
|
||
| let eventArgsSchema = S.literal(%raw(`null`))->S.variant((. _) => ()) | ||
|
|
||
| external convertHyperSyncEventArgs: HyperSyncClient.Decoder.decodedEvent => eventArgs = "%identity" |
There was a problem hiding this comment.
The only regression is that it's not runtime-free anymore, but everything else should work the same as before.
There was a problem hiding this comment.
Doesn't the Utils.magic function become zero cost during optimization steps?
There was a problem hiding this comment.
Only when the function is called from the same file
| Params(Vec<EventParam>), | ||
| Data(RescriptTypeIdent), |
There was a problem hiding this comment.
I'm pretty keen to use the same way of generating types for EVM in future. It's nice because it easily supports nested record types which we currently just inline as tuples.
There was a problem hiding this comment.
Sounds good, the only problem I see is building a hyperSyncConverter function
There was a problem hiding this comment.
Hmmm, yeah, but we should be able to lookup nested types and codegen a converter without too much trouble.
There was a problem hiding this comment.
Should work, but what about the is_indexed?
There was a problem hiding this comment.
Should work, but what about the
is_indexed?
Well, we should generate the converter from the EVM event, not the rescript type. If you add an index to a nested struct/tuple/array, the actual data doesn't get stored on chain. Just a keccak hash so we don't really have to handle params that are a nested index structure.
| name: event_config.name, | ||
| event, | ||
| payload: EventPayload::Data(log.data_type), | ||
| topic0: log.id, |
There was a problem hiding this comment.
Is it appropriate to call fuel's log.id a sighash?
If so maybe we rename topic0 to sighash as a convention. Since topic0 is the sighash of an evm event.
There was a problem hiding this comment.
Yes, I think it's something like this. I'll change this in the next PR.
| let event: NormalizedEthAbiEvent = | ||
| Event::get_abi_event(&format!("{}()", event_config.name), &None)?.into(); |
There was a problem hiding this comment.
Cool so this is just a stub with an empty event for now? Need to relook at the data structure.
There was a problem hiding this comment.
Unfortunately it's still used in some places, so I couldn't get rid of it yet.
| const DECODE_HYPER_FUEL_DATA_CODE: &'static str = | ||
| "(_) => Js.Exn.raiseError(\"HyperFuel decoder not implemented\")"; | ||
|
|
||
| pub fn generate_convert_hyper_sync_event_args_code(params: &Vec<EventParam>) -> String { |
There was a problem hiding this comment.
Can we handle the empty vec in this function so the context makes a bit more sense?
So check if it's empty and return the (Utils.magic: HyperSyncClient.Decoder.decodedEvent => eventArgs) here if so.
| let template_params = params | ||
| .iter() | ||
| .map(|input| { | ||
| let res_type = abi_to_rescript_type(&input.into()); | ||
| let js_name = input.name.to_string(); | ||
| EventParamTypeTemplate { | ||
| res_name: RescriptRecordField::to_valid_res_name(&js_name), | ||
| js_name, | ||
| default_value_rescript: res_type.get_default_value_rescript(), | ||
| default_value_non_rescript: res_type | ||
| .get_default_value_non_rescript(), | ||
| res_type: res_type.to_string(), | ||
| is_eth_address: res_type == RescriptTypeIdent::Address, | ||
| } | ||
| }) | ||
| .collect::<Vec<_>>(); | ||
|
|
||
| let data_type_expr = RescriptTypeExpr::Record( | ||
| params | ||
| .iter() | ||
| .map(|p| { | ||
| RescriptRecordField::new( | ||
| p.name.to_string(), | ||
| abi_to_rescript_type(&p.into()), | ||
| ) | ||
| }) | ||
| .collect(), | ||
| ); |
There was a problem hiding this comment.
Lets remove the above if else check and then if params are empty just make unit type expression and the rest of the logic can remain the same.
| name, | ||
| params: vec![], | ||
| data_type: type_indent.to_string(), | ||
| data_schema_code: type_indent.to_rescript_schema(), | ||
| topic0: config_event.topic0.to_string(), | ||
| convert_hyper_sync_event_args_code: | ||
| "(Utils.magic: HyperSyncClient.Decoder.decodedEvent => eventArgs)".to_string(), | ||
| decode_hyper_fuel_data_code: Self::DECODE_HYPER_FUEL_DATA_CODE.to_string(), | ||
| }), |
There was a problem hiding this comment.
Actually this case can be covered as well. All we want to do on the match of these types is return a rescript type expression.
There was a problem hiding this comment.
It'll change in the future with the decode_hyper_fuel_data_code implementation.
| vec![], | ||
| ); | ||
|
|
||
| let expected = r#"type myRecord = {@as("module") module_: bool, @as("") _: bool, @as("1") _1: bool, @as("Capitalized") capitalized: bool, dashed-field: bool}"#.to_string(); |
There was a problem hiding this comment.
What's happening with dash-field? If you want, there's a lib I installed called convert_case which you could transform kebab to camel or snake case for eg.
There was a problem hiding this comment.
It'll codegen like this dashed-field: bool and break during compilation. I think we don't have a case for this yet, so I just ignored it.
JonoPrest
left a comment
There was a problem hiding this comment.
Looks great Dmitry. I see a lot of conflicts about to happen with my current PR 😅
topic0var