Skip to content

Commit

Permalink
Use new solana mechanism for return data
Browse files Browse the repository at this point in the history
Requires:
 - solana-labs/solana#19548
 - solana-labs/solana#19318

Signed-off-by: Sean Young <[email protected]>
  • Loading branch information
seanyoung committed Sep 1, 2021
1 parent 0e31a53 commit c7514ad
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 223 deletions.
35 changes: 26 additions & 9 deletions integration/solana/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const default_url: string = "http://localhost:8899";

export async function establishConnection(): Promise<TestConnection> {
let url = process.env.RPC_URL || default_url;
let connection = new Connection(url, 'recent');
let connection = new Connection(url, 'confirmed');
const version = await connection.getVersion();
console.log('Connection to cluster established:', url, version);

Expand Down Expand Up @@ -101,7 +101,7 @@ class TestConnection {
[this.payerAccount, account],
{
skipPreflight: false,
commitment: 'recent',
commitment: 'confirmed',
preflightCommitment: undefined,
},
);
Expand Down Expand Up @@ -190,7 +190,7 @@ class Program {
[test.payerAccount],
{
skipPreflight: false,
commitment: 'recent',
commitment: 'confirmed',
preflightCommitment: undefined,
},
);
Expand Down Expand Up @@ -232,24 +232,41 @@ class Program {

signers.unshift(test.payerAccount);

await sendAndConfirmTransaction(
let signature = await sendAndConfirmTransaction(
test.connection,
new Transaction().add(instruction),
signers,
{
skipPreflight: false,
commitment: 'recent',
commitment: 'confirmed',
preflightCommitment: undefined,
},
);

if (abi.outputs?.length) {
const accountInfo = await test.connection.getAccountInfo(this.contractStorageAccount.publicKey);
const parsedTx = await test.connection.getParsedConfirmedTransaction(
signature,
);

let encoded = Buffer.from([]);

const return_data_prefix = 'Program return data: ';

let length = Number(accountInfo!.data.readUInt32LE(4));
let offset = Number(accountInfo!.data.readUInt32LE(8));
let seen = 0;

let encoded = accountInfo!.data.slice(offset, length + offset);
for (let message of parsedTx!.meta?.logMessages!) {
if (message.startsWith(return_data_prefix)) {
if (seen != 0) {
throw 'More than one return data seen';
}
encoded = Buffer.from(message.slice(return_data_prefix.length), 'base64')
seen += 1;
}
}

if (seen == 0) {
throw 'return data not set';
}

let returns = Web3EthAbi.decodeParameters(abi.outputs!, encoded.toString('hex'));

Expand Down
72 changes: 13 additions & 59 deletions src/emit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6167,68 +6167,22 @@ impl<'a> Binary<'a> {
.unwrap()
.into_pointer_value()
} else {
// Get the type name of the struct we are point to
let struct_ty = vector
.into_pointer_value()
.get_type()
.get_element_type()
.into_struct_type();
let name = struct_ty.get_name().unwrap();

if name == CStr::from_bytes_with_nul(b"struct.SolAccountInfo\0").unwrap() {
// load the data pointer
let data = self
.builder
.build_load(
self.builder
.build_struct_gep(vector.into_pointer_value(), 3, "data")
.unwrap(),
"data",
)
.into_pointer_value();

// get the offset of the return data
let header_ptr = self.builder.build_pointer_cast(
data,
self.context.i32_type().ptr_type(AddressSpace::Generic),
"header_ptr",
);

let data_ptr = unsafe {
self.builder.build_gep(
header_ptr,
&[self.context.i64_type().const_int(2, false)],
"data_ptr",
)
};

let offset = self.builder.build_load(data_ptr, "offset").into_int_value();

let v = unsafe { self.builder.build_gep(data, &[offset], "data") };

self.builder.build_pointer_cast(
v,
self.context.i8_type().ptr_type(AddressSpace::Generic),
let data = unsafe {
self.builder.build_gep(
vector.into_pointer_value(),
&[
self.context.i32_type().const_zero(),
self.context.i32_type().const_int(2, false),
],
"data",
)
} else {
let data = unsafe {
self.builder.build_gep(
vector.into_pointer_value(),
&[
self.context.i32_type().const_zero(),
self.context.i32_type().const_int(2, false),
],
"data",
)
};
};

self.builder.build_pointer_cast(
data,
self.context.i8_type().ptr_type(AddressSpace::Generic),
"data",
)
}
self.builder.build_pointer_cast(
data,
self.context.i8_type().ptr_type(AddressSpace::Generic),
"data",
)
}
}

Expand Down
Loading

0 comments on commit c7514ad

Please sign in to comment.