Przeglądaj źródła

Add value to instruction

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 lat temu
rodzic
commit
89ec275940

+ 4 - 0
integration/solana/index.ts

@@ -173,6 +173,7 @@ class Program {
         const data = Buffer.concat([
             this.contractStorageAccount.publicKey.toBuffer(),
             test.payerAccount.publicKey.toBuffer(),
+            Buffer.from('0000000000000000', 'hex'),
             Buffer.from(hash.substr(2, 8), 'hex'),
             this.encode_seeds(seeds),
             Buffer.from(input.replace('0x', ''), 'hex')
@@ -206,6 +207,7 @@ class Program {
         const data = Buffer.concat([
             this.contractStorageAccount.publicKey.toBuffer(),
             test.payerAccount.publicKey.toBuffer(),
+            Buffer.from('0000000000000000', 'hex'),
             Buffer.from('00000000', 'hex'),
             this.encode_seeds(seeds),
             Buffer.from(input.replace('0x', ''), 'hex')
@@ -296,6 +298,7 @@ class Program {
         const data = Buffer.concat([
             this.contractStorageAccount.publicKey.toBuffer(),
             test.payerAccount.publicKey.toBuffer(),
+            Buffer.from('0000000000000000', 'hex'),
             Buffer.from('00000000', 'hex'),
             this.encode_seeds(seeds),
             Buffer.from(input.replace('0x', ''), 'hex')
@@ -363,6 +366,7 @@ class Program {
         const data = Buffer.concat([
             this.contractStorageAccount.publicKey.toBuffer(),
             test.payerAccount.publicKey.toBuffer(),
+            Buffer.from('0000000000000000', 'hex'),
             Buffer.from('00000000', 'hex'),
             this.encode_seeds(seeds),
             Buffer.from(input.replace('0x', ''), 'hex')

+ 6 - 2
src/codegen/expression.rs

@@ -1343,6 +1343,7 @@ pub fn emit_function_call(
                                 Builtin::GetAddress,
                                 Vec::new(),
                             ),
+                            value.clone(),
                             Expression::NumberLiteral(*loc, Type::Bytes(4), BigInt::zero()),
                             Expression::NumberLiteral(*loc, Type::Bytes(1), BigInt::zero()),
                             args,
@@ -1351,6 +1352,7 @@ pub fn emit_function_call(
                         tys: vec![
                             Type::Address(false),
                             Type::Address(false),
+                            Type::Uint(64),
                             Type::Bytes(4),
                             Type::Bytes(1),
                             Type::DynamicBytes,
@@ -1410,8 +1412,9 @@ pub fn emit_function_call(
                 let (payload, address) = if ns.target == Target::Solana {
                     tys.insert(0, Type::Address(false));
                     tys.insert(1, Type::Address(false));
-                    tys.insert(2, Type::Bytes(4));
-                    tys.insert(3, Type::Bytes(1));
+                    tys.insert(2, Type::Uint(64));
+                    tys.insert(3, Type::Bytes(4));
+                    tys.insert(4, Type::Bytes(1));
 
                     (
                         Expression::AbiEncode {
@@ -1425,6 +1428,7 @@ pub fn emit_function_call(
                                     Builtin::GetAddress,
                                     Vec::new(),
                                 ),
+                                value.clone(),
                                 Expression::NumberLiteral(*loc, Type::Bytes(4), BigInt::zero()),
                                 Expression::NumberLiteral(*loc, Type::Bytes(1), BigInt::zero()),
                                 Expression::NumberLiteral(

+ 13 - 9
src/emit/solana.rs

@@ -2554,7 +2554,11 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
         ns: &ast::Namespace,
     ) {
         // abi encode the arguments. The
-        let mut tys = vec![ast::Type::Bytes(4), ast::Type::Bytes(1)];
+        let mut tys = vec![
+            ast::Type::Uint(64),
+            ast::Type::Bytes(4),
+            ast::Type::Bytes(1),
+        ];
 
         if let Some(function_no) = constructor_no {
             for param in &ns.functions[function_no].params {
@@ -2562,7 +2566,14 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             }
         };
 
+        let value = if let Some(value) = value {
+            value
+        } else {
+            binary.context.i64_type().const_zero()
+        };
+
         let packed = [
+            value.into(),
             binary
                 .context
                 .i32_type()
@@ -2618,19 +2629,13 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
             "space",
         );
 
-        let value = if let Some(value) = value {
-            value
-        } else {
-            binary.context.i64_type().const_zero()
-        };
-
         let sol_params = function.get_last_param().unwrap().into_pointer_value();
 
         let create_contract = binary.module.get_function("create_contract").unwrap();
 
         let arg4 = binary.builder.build_pointer_cast(
             sol_params,
-            create_contract.get_type().get_param_types()[4].into_pointer_type(),
+            create_contract.get_type().get_param_types()[3].into_pointer_type(),
             "",
         );
 
@@ -2641,7 +2646,6 @@ impl<'a> TargetRuntime<'a> for SolanaTarget {
                 &[
                     payload.into(),
                     malloc_length.into(),
-                    value.into(),
                     space.into(),
                     arg4.into(),
                 ],

BIN
stdlib/bpf/solana.bc


+ 1 - 1
stdlib/solana.c

@@ -113,7 +113,7 @@ uint64_t external_call(uint8_t *input, uint32_t input_len, SolParameters *params
 }
 
 // This function creates a new address and calls its constructor.
-uint64_t create_contract(uint8_t *input, uint32_t input_len, uint64_t lamports, uint64_t space, SolParameters *params)
+uint64_t create_contract(uint8_t *input, uint32_t input_len, uint64_t space, SolParameters *params)
 {
     SolAccountInfo *new_acc = NULL;
     const SolSignerSeed *seed = NULL;

+ 4 - 0
stdlib/solana_sdk.h

@@ -243,6 +243,7 @@ typedef struct
   SolSignerSeed seeds[10];
   int seeds_len;
   const SolAccountInfo *ka_instructions;
+  uint64_t value;
 } SolParameters;
 
 /**
@@ -369,6 +370,9 @@ static uint64_t sol_deserialize(
   params->sender = (SolPubkey *)input;
   input += SIZE_PUBKEY;
   data_len -= SIZE_PUBKEY;
+  params->value = *(uint64_t *)input;
+  input += sizeof(uint64_t);
+  data_len -= sizeof(uint64_t);
 
   // FIXME: check that sender is a signer
 

+ 4 - 2
tests/solana.rs

@@ -1258,7 +1258,7 @@ impl VirtualMachine {
 
         println!("constructor for {}", hex::encode(&program.data));
 
-        let mut calldata = VirtualMachine::input(&program.data, &account_new(), name, &[]);
+        let mut calldata = VirtualMachine::input(&program.data, &account_new(), 0, name, &[]);
 
         if let Some(constructor) = &program.abi.as_ref().unwrap().constructor {
             calldata.extend(&constructor.encode_input(vec![], args).unwrap());
@@ -1277,7 +1277,7 @@ impl VirtualMachine {
 
         println!("function for {}", hex::encode(&program.data));
 
-        let mut calldata = VirtualMachine::input(&program.data, &account_new(), name, seeds);
+        let mut calldata = VirtualMachine::input(&program.data, &account_new(), 0, name, seeds);
 
         println!("input: {} seeds {:?}", hex::encode(&calldata), seeds);
 
@@ -1306,11 +1306,13 @@ impl VirtualMachine {
     fn input(
         recv: &Account,
         sender: &Account,
+        value: u64,
         name: &str,
         seeds: &[&(Account, Vec<u8>)],
     ) -> Vec<u8> {
         let mut calldata: Vec<u8> = recv.to_vec();
         calldata.extend_from_slice(sender);
+        calldata.extend_from_slice(&value.to_le_bytes());
 
         let mut hasher = Keccak::v256();
         let mut hash = [0u8; 32];