Bladeren bron

Implement msg.data for Solana

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 jaren geleden
bovenliggende
commit
8dc725df93
4 gewijzigde bestanden met toevoegingen van 87 en 18 verwijderingen
  1. 18 0
      src/emit/ewasm.rs
  2. 0 17
      src/emit/mod.rs
  3. 46 0
      src/emit/solana.rs
  4. 23 1
      tests/solana_tests/builtin.rs

+ 18 - 0
src/emit/ewasm.rs

@@ -1922,6 +1922,24 @@ impl<'a> TargetRuntime<'a> for EwasmTarget {
             ast::Expression::Builtin(_, _, ast::Builtin::Value, _) => {
                 single_value_stack!("value", "getCallValue", ns.value_length as u32 * 8)
             }
+            ast::Expression::Builtin(_, _, ast::Builtin::Calldata, _) => binary
+                .builder
+                .build_call(
+                    binary.module.get_function("vector_new").unwrap(),
+                    &[
+                        binary
+                            .builder
+                            .build_load(binary.calldata_len.as_pointer_value(), "calldata_len"),
+                        binary.context.i32_type().const_int(1, false).into(),
+                        binary
+                            .builder
+                            .build_load(binary.calldata_data.as_pointer_value(), "calldata_data"),
+                    ],
+                    "",
+                )
+                .try_as_basic_value()
+                .left()
+                .unwrap(),
             ast::Expression::Builtin(_, _, ast::Builtin::BlockHash, args) => {
                 let block_number = self.expression(binary, &args[0], vartab, function, ns);
 

+ 0 - 17
src/emit/mod.rs

@@ -2570,23 +2570,6 @@ pub trait TargetRuntime<'a> {
                     ns,
                 )
                 .into(),
-            Expression::Builtin(_, _, Builtin::Calldata, _) if ns.target != Target::Substrate => {
-                bin.builder
-                    .build_call(
-                        bin.module.get_function("vector_new").unwrap(),
-                        &[
-                            bin.builder
-                                .build_load(bin.calldata_len.as_pointer_value(), "calldata_len"),
-                            bin.context.i32_type().const_int(1, false).into(),
-                            bin.builder
-                                .build_load(bin.calldata_data.as_pointer_value(), "calldata_data"),
-                        ],
-                        "",
-                    )
-                    .try_as_basic_value()
-                    .left()
-                    .unwrap()
-            }
             Expression::Builtin(_, _, Builtin::Signature, _) => {
                 // need to byte-reverse selector
                 let selector = bin.build_alloca(function, bin.context.i32_type(), "selector");

+ 46 - 0
src/emit/solana.rs

@@ -3209,6 +3209,52 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
 
                 binary.builder.build_load(value, "self_address")
             }
+            ast::Expression::Builtin(_, _, ast::Builtin::Calldata, _) => {
+                let sol_params = self.sol_parameters(binary);
+
+                let input = binary
+                    .builder
+                    .build_load(
+                        binary
+                            .builder
+                            .build_struct_gep(sol_params, 5, "input")
+                            .unwrap(),
+                        "data",
+                    )
+                    .into_pointer_value();
+
+                let input_len = binary
+                    .builder
+                    .build_load(
+                        binary
+                            .builder
+                            .build_struct_gep(sol_params, 6, "input_len")
+                            .unwrap(),
+                        "data_len",
+                    )
+                    .into_int_value();
+
+                let input_len = binary.builder.build_int_truncate(
+                    input_len,
+                    binary.context.i32_type(),
+                    "input_len",
+                );
+
+                binary
+                    .builder
+                    .build_call(
+                        binary.module.get_function("vector_new").unwrap(),
+                        &[
+                            input_len.into(),
+                            binary.context.i32_type().const_int(1, false).into(),
+                            input.into(),
+                        ],
+                        "",
+                    )
+                    .try_as_basic_value()
+                    .left()
+                    .unwrap()
+            }
             ast::Expression::Builtin(_, _, ast::Builtin::SignatureVerify, args) => {
                 assert_eq!(args.len(), 3);
 

+ 23 - 1
tests/solana_tests/builtin.rs

@@ -2,7 +2,7 @@ use crate::build_solidity;
 use ethabi::Token;
 
 #[test]
-fn timestamp() {
+fn builtins() {
     let mut vm = build_solidity(
         r#"
         contract timestamp {
@@ -15,6 +15,9 @@ fn timestamp() {
             function mr_blocknumber() public returns (uint64) {
                 return block.number;
             }
+            function msg_data(uint32 x) public returns (bytes) {
+                return msg.data;
+            }
         }"#,
     );
 
@@ -40,4 +43,23 @@ fn timestamp() {
         returns,
         vec![Token::Uint(ethereum_types::U256::from(70818331))]
     );
+
+    let returns = vm.function(
+        "msg_data",
+        &[Token::Uint(ethereum_types::U256::from(0xdeadcafeu32))],
+        &[],
+        0,
+    );
+
+    if let Token::Bytes(v) = &returns[0] {
+        println!("{}", hex::encode(v));
+    }
+
+    assert_eq!(
+        returns,
+        vec![Token::Bytes(
+            hex::decode("84da38e000000000000000000000000000000000000000000000000000000000deadcafe")
+                .unwrap()
+        )]
+    );
 }