From 0f238d06504aa751839c70dc3ba847de6aae1b6e Mon Sep 17 00:00:00 2001 From: majabbour <59592028+majabbour@users.noreply.github.com> Date: Tue, 19 Jul 2022 13:04:23 -0500 Subject: [PATCH 01/13] changed c return value of update price to indicate aggregation (#190) * changed c return value of update price to indicate aggregation * forgot to add bindings * removed the need for casting * fixed update_no_fail * removed unnecessary docker packages --- program/c/src/oracle/oracle.h | 1 + 1 file changed, 1 insertion(+) diff --git a/program/c/src/oracle/oracle.h b/program/c/src/oracle/oracle.h index 6ca196855..ed2c177ac 100644 --- a/program/c/src/oracle/oracle.h +++ b/program/c/src/oracle/oracle.h @@ -6,6 +6,7 @@ extern "C" { #endif + //A return value indicating that the aggregate price was updated //this triggers SMA trackers to update //values 0-14 are defined in solana_sdk.h (v1.10.31 ) From 3a2140b814b8ca017dc904e091bcc26c280aec43 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Wed, 20 Jul 2022 14:19:01 +0000 Subject: [PATCH 02/13] timeless coments --- program/c/src/oracle/oracle.h | 1 - 1 file changed, 1 deletion(-) diff --git a/program/c/src/oracle/oracle.h b/program/c/src/oracle/oracle.h index ed2c177ac..6ca196855 100644 --- a/program/c/src/oracle/oracle.h +++ b/program/c/src/oracle/oracle.h @@ -6,7 +6,6 @@ extern "C" { #endif - //A return value indicating that the aggregate price was updated //this triggers SMA trackers to update //values 0-14 are defined in solana_sdk.h (v1.10.31 ) From 13377c8d668082832b9e5fbc4e2ffdd7585ee64c Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Wed, 20 Jul 2022 14:24:55 +0000 Subject: [PATCH 03/13] added comment clarifying that 0 is success --- program/rust/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index 27c2ba0f5..a297a092c 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -25,4 +25,4 @@ pub extern "C" fn entrypoint(input: *mut u8) -> u64 { } else { return c_ret_val; } -} +} \ No newline at end of file From a0556d7a2c414fcfb9b75a7287841b1ffbb9428b Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Wed, 20 Jul 2022 20:26:40 +0000 Subject: [PATCH 04/13] a convinient way to derive traits --- program/rust/Cargo.toml | 5 +++++ program/rust/build.rs | 18 ++++++++++++++++++ program/rust/build_utils.rs | 25 +++++++++++++++++++++++++ program/rust/src/c_oracle_header.rs | 8 ++++++++ program/rust/src/lib.rs | 2 -- scripts/build-bpf.sh | 4 ++-- 6 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 program/rust/build_utils.rs create mode 100644 program/rust/src/c_oracle_header.rs diff --git a/program/rust/Cargo.toml b/program/rust/Cargo.toml index 91b35559f..782b40b6f 100644 --- a/program/rust/Cargo.toml +++ b/program/rust/Cargo.toml @@ -7,8 +7,13 @@ edition = "2021" license = "Apache 2.0" publish = false +[build-dependencies] +bindgen = "0.60.1" + [dependencies] solana-program = "=1.10.29" +borsh = "0.9" + [lib] crate-type = ["cdylib", "lib"] diff --git a/program/rust/build.rs b/program/rust/build.rs index 60da04a8d..82a4ac671 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -1,3 +1,21 @@ +mod build_utils; +use bindgen; +use std::collections::HashMap; +use std::vec::Vec; + + fn main() { println!("cargo:rustc-link-search=../c/target"); + + let borsh_derives: Vec = vec!["BorshSerialize".to_string(), "BorshDeserialize".to_string()]; + + let parser = build_utils::DeriveAdderParserCallback{types_to_traits: HashMap::from([ + ("cmd_hdr", borsh_derives) + //map more struct names to traits here, be sure that the definitions of your traites + //are included in c_oracle_header.rs + ])}; + + //generate and write bindings + let bindings = bindgen::Builder::default().header("./src/bindings.h").parse_callbacks(Box::new(parser)).generate().expect("Unable to generate bindings"); + bindings.write_to_file("./bindings.rs").expect("Couldn't write bindings!"); } diff --git a/program/rust/build_utils.rs b/program/rust/build_utils.rs new file mode 100644 index 000000000..7d5a97b36 --- /dev/null +++ b/program/rust/build_utils.rs @@ -0,0 +1,25 @@ +use bindgen; +use std::panic::UnwindSafe; +use std::collections::HashMap; +///This type stores a hashmap from structnames +///to vectors of trait names, and ensures +///that the traits of each struct are added to its +///definition when an instance of this struct +///is provided as a ParseCallback for bindgen +#[derive(Debug)] +pub struct DeriveAdderParserCallback<'a>{ + pub types_to_traits: HashMap<&'a str, Vec> , +} + +//this is required to implement the callback trait +impl UnwindSafe for DeriveAdderParserCallback<'_> {} + +impl bindgen::callbacks::ParseCallbacks for DeriveAdderParserCallback<'_>{ + fn add_derives(&self, _name: &str) -> Vec{ + let traits = self.types_to_traits.get(_name); + match traits{ + Some(trait_names)=>trait_names.to_vec(), + None => vec![], + } + } +} \ No newline at end of file diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs new file mode 100644 index 000000000..839858e11 --- /dev/null +++ b/program/rust/src/c_oracle_header.rs @@ -0,0 +1,8 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +//All the custom trait imports should go here +use borsh::{BorshSerialize, BorshDeserialize}; +//bindings.rs is generated by build.rs to include +//things defined in bindings.h +include!("../bindings.rs"); \ No newline at end of file diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index a297a092c..375ba3503 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -1,5 +1,3 @@ -//c_oracle_header is auto generated by build_bpf.sh -//to reflect the current status of oracle.h mod c_oracle_header; mod time_machine_types; diff --git a/scripts/build-bpf.sh b/scripts/build-bpf.sh index 95818a2ad..08d1a72e1 100755 --- a/scripts/build-bpf.sh +++ b/scripts/build-bpf.sh @@ -40,8 +40,8 @@ rm ./target/*-keypair.json #build Rust and link it with C cd "${RUST_DIR}" -cargo install bindgen -bindgen ./src/bindings.h -o ./src/c_oracle_header.rs +#cargo install bindgen +#bindgen ./src/bindings.h -o ./src/c_oracle_header.rs cargo clean cargo test cargo clean From 2abb63be1b7c847b7ec1fa1f600474ee130042af Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Thu, 21 Jul 2022 15:31:18 +0000 Subject: [PATCH 05/13] silenced unused bindings warnings --- program/rust/src/c_oracle_header.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index 839858e11..8073e46a4 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -1,6 +1,9 @@ #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] +//we do not use all the variables in oracle.h, so this helps with the warnings +#![allow(unused_variables)] +#![allow(dead_code)] //All the custom trait imports should go here use borsh::{BorshSerialize, BorshDeserialize}; //bindings.rs is generated by build.rs to include From cb1a3b80f65078b685425df2668b98eef1c28803 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Thu, 21 Jul 2022 15:36:27 +0000 Subject: [PATCH 06/13] removed dead code --- scripts/build-bpf.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/build-bpf.sh b/scripts/build-bpf.sh index 08d1a72e1..8880ce140 100755 --- a/scripts/build-bpf.sh +++ b/scripts/build-bpf.sh @@ -40,8 +40,6 @@ rm ./target/*-keypair.json #build Rust and link it with C cd "${RUST_DIR}" -#cargo install bindgen -#bindgen ./src/bindings.h -o ./src/c_oracle_header.rs cargo clean cargo test cargo clean From 80ac6a07d75df9d463478c3872f293927f1c1d3a Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Thu, 21 Jul 2022 17:20:11 +0000 Subject: [PATCH 07/13] added a comment explaining the structure --- program/rust/src/lib.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index 375ba3503..46884dc60 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -1,7 +1,26 @@ mod c_oracle_header; mod time_machine_types; -//do not link with C during unit tests (which are built in native architecture, unlike libpyth.o) + +//Below is a high lever description of the rust/c setup. + +//As we migrate from C to Rust, our Rust code needs to be able to interract with C +//build-bpf.sh is set up to compile the C code into a bpf archive file, that build.rs +//is set up to link the rust targets to. This enables to interact with the c_entrypoint +//as well as similarly declare other C functions in Rust and call them + +//We also generate bindings for the types and constants in oracle.h (as well as other things +//included in bindings.h), these bindings can be accessed through c_oracle_header.rs +//Bindings allow us to access type definitions, function definitions and constants. In order to +//add traits to the bindings, we use the parser in build.rs. The traits must be defined/included +//at the the top of c_oracle_headers.rs. One of the most important traits we deal are the Borsh +//serialization traits. + +//the only limitation of our set up is that we can not unit test in rust, anything that calls +//a c function. Though we can test functions that use constants/types defined in oracle.h + + +//do not link with C during unit tests (which are built in native architecture, unlike libpyth.o) #[cfg(target_arch = "bpf")] #[link(name = "cpyth")] extern "C" { From abd8e2e495a326c8f2c67fe954c2e00cb23a81db Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Thu, 21 Jul 2022 17:41:58 +0000 Subject: [PATCH 08/13] changed importing style --- program/rust/build.rs | 4 ++-- program/rust/build_utils.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index 82a4ac671..a069e7370 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -1,5 +1,5 @@ mod build_utils; -use bindgen; +use bindgen::Builder; use std::collections::HashMap; use std::vec::Vec; @@ -16,6 +16,6 @@ fn main() { ])}; //generate and write bindings - let bindings = bindgen::Builder::default().header("./src/bindings.h").parse_callbacks(Box::new(parser)).generate().expect("Unable to generate bindings"); + let bindings = Builder::default().header("./src/bindings.h").parse_callbacks(Box::new(parser)).generate().expect("Unable to generate bindings"); bindings.write_to_file("./bindings.rs").expect("Couldn't write bindings!"); } diff --git a/program/rust/build_utils.rs b/program/rust/build_utils.rs index 7d5a97b36..83635de80 100644 --- a/program/rust/build_utils.rs +++ b/program/rust/build_utils.rs @@ -1,4 +1,4 @@ -use bindgen; +use bindgen::callbacks::ParseCallbacks; use std::panic::UnwindSafe; use std::collections::HashMap; ///This type stores a hashmap from structnames @@ -14,7 +14,7 @@ pub struct DeriveAdderParserCallback<'a>{ //this is required to implement the callback trait impl UnwindSafe for DeriveAdderParserCallback<'_> {} -impl bindgen::callbacks::ParseCallbacks for DeriveAdderParserCallback<'_>{ +impl ParseCallbacks for DeriveAdderParserCallback<'_>{ fn add_derives(&self, _name: &str) -> Vec{ let traits = self.types_to_traits.get(_name); match traits{ From fba7985ba882b3ecd01792fa169f6502dcc5685d Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Thu, 21 Jul 2022 18:04:55 +0000 Subject: [PATCH 09/13] called fmt on bindings output --- program/rust/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index a069e7370..750ec1a40 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -16,6 +16,6 @@ fn main() { ])}; //generate and write bindings - let bindings = Builder::default().header("./src/bindings.h").parse_callbacks(Box::new(parser)).generate().expect("Unable to generate bindings"); + let bindings = Builder::default().header("./src/bindings.h").parse_callbacks(Box::new(parser)).rustfmt_bindings(true).generate().expect("Unable to generate bindings"); bindings.write_to_file("./bindings.rs").expect("Couldn't write bindings!"); } From c6fa336e34fa7cc40300f1bc4c2d807eb1bca288 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Thu, 21 Jul 2022 19:12:34 +0000 Subject: [PATCH 10/13] added register_traits method --- program/rust/build.rs | 9 +++------ program/rust/build_utils.rs | 14 +++++++++++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index 750ec1a40..0d7706c68 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -1,6 +1,5 @@ mod build_utils; use bindgen::Builder; -use std::collections::HashMap; use std::vec::Vec; @@ -9,11 +8,9 @@ fn main() { let borsh_derives: Vec = vec!["BorshSerialize".to_string(), "BorshDeserialize".to_string()]; - let parser = build_utils::DeriveAdderParserCallback{types_to_traits: HashMap::from([ - ("cmd_hdr", borsh_derives) - //map more struct names to traits here, be sure that the definitions of your traites - //are included in c_oracle_header.rs - ])}; + //make a parser and to it type, traits pairs + let mut parser = build_utils::DeriveAdderParserCallback::new(); + parser.register_traits("cmd_hdr", borsh_derives); //generate and write bindings let bindings = Builder::default().header("./src/bindings.h").parse_callbacks(Box::new(parser)).rustfmt_bindings(true).generate().expect("Unable to generate bindings"); diff --git a/program/rust/build_utils.rs b/program/rust/build_utils.rs index 83635de80..25bb4c28c 100644 --- a/program/rust/build_utils.rs +++ b/program/rust/build_utils.rs @@ -6,11 +6,23 @@ use std::collections::HashMap; ///that the traits of each struct are added to its ///definition when an instance of this struct ///is provided as a ParseCallback for bindgen -#[derive(Debug)] +#[derive(Debug, Default)] pub struct DeriveAdderParserCallback<'a>{ pub types_to_traits: HashMap<&'a str, Vec> , } +impl <'a> DeriveAdderParserCallback<'a>{ + ///create a parser that does not add any traits + pub fn new() -> Self { + Default::default() + } + //add pairs of types and their desired traits + pub fn register_traits(&mut self, type_name: &'a str ,traits: Vec){ + self.types_to_traits.insert(&type_name, traits); + } + +} + //this is required to implement the callback trait impl UnwindSafe for DeriveAdderParserCallback<'_> {} From 371d45362db98c286e484f59c58d77cd2a90edb6 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Thu, 21 Jul 2022 19:28:47 +0000 Subject: [PATCH 11/13] removed unnecessary match --- program/rust/build_utils.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/program/rust/build_utils.rs b/program/rust/build_utils.rs index 25bb4c28c..9c552481a 100644 --- a/program/rust/build_utils.rs +++ b/program/rust/build_utils.rs @@ -28,10 +28,6 @@ impl UnwindSafe for DeriveAdderParserCallback<'_> {} impl ParseCallbacks for DeriveAdderParserCallback<'_>{ fn add_derives(&self, _name: &str) -> Vec{ - let traits = self.types_to_traits.get(_name); - match traits{ - Some(trait_names)=>trait_names.to_vec(), - None => vec![], - } + self.types_to_traits.get(_name).unwrap_or(&Vec::::new()).to_vec() } } \ No newline at end of file From 5871ab8ba02296896389225fc17c4fd484f344e9 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Thu, 21 Jul 2022 21:48:16 +0000 Subject: [PATCH 12/13] fixed formatting --- program/rust/build.rs | 17 ++++++++++++----- program/rust/build_utils.rs | 22 ++++++++++++---------- program/rust/src/c_oracle_header.rs | 4 ++-- program/rust/src/lib.rs | 6 ++---- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index 0d7706c68..e7ab7dd65 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -2,17 +2,24 @@ mod build_utils; use bindgen::Builder; use std::vec::Vec; - fn main() { println!("cargo:rustc-link-search=../c/target"); - - let borsh_derives: Vec = vec!["BorshSerialize".to_string(), "BorshDeserialize".to_string()]; + + let borsh_derives: Vec = + vec!["BorshSerialize".to_string(), "BorshDeserialize".to_string()]; //make a parser and to it type, traits pairs let mut parser = build_utils::DeriveAdderParserCallback::new(); parser.register_traits("cmd_hdr", borsh_derives); //generate and write bindings - let bindings = Builder::default().header("./src/bindings.h").parse_callbacks(Box::new(parser)).rustfmt_bindings(true).generate().expect("Unable to generate bindings"); - bindings.write_to_file("./bindings.rs").expect("Couldn't write bindings!"); + let bindings = Builder::default() + .header("./src/bindings.h") + .parse_callbacks(Box::new(parser)) + .rustfmt_bindings(true) + .generate() + .expect("Unable to generate bindings"); + bindings + .write_to_file("./bindings.rs") + .expect("Couldn't write bindings!"); } diff --git a/program/rust/build_utils.rs b/program/rust/build_utils.rs index 9c552481a..7848d73a3 100644 --- a/program/rust/build_utils.rs +++ b/program/rust/build_utils.rs @@ -1,33 +1,35 @@ use bindgen::callbacks::ParseCallbacks; -use std::panic::UnwindSafe; use std::collections::HashMap; +use std::panic::UnwindSafe; ///This type stores a hashmap from structnames ///to vectors of trait names, and ensures ///that the traits of each struct are added to its ///definition when an instance of this struct ///is provided as a ParseCallback for bindgen #[derive(Debug, Default)] -pub struct DeriveAdderParserCallback<'a>{ - pub types_to_traits: HashMap<&'a str, Vec> , +pub struct DeriveAdderParserCallback<'a> { + pub types_to_traits: HashMap<&'a str, Vec>, } -impl <'a> DeriveAdderParserCallback<'a>{ +impl<'a> DeriveAdderParserCallback<'a> { ///create a parser that does not add any traits pub fn new() -> Self { Default::default() } //add pairs of types and their desired traits - pub fn register_traits(&mut self, type_name: &'a str ,traits: Vec){ + pub fn register_traits(&mut self, type_name: &'a str, traits: Vec) { self.types_to_traits.insert(&type_name, traits); } - } //this is required to implement the callback trait impl UnwindSafe for DeriveAdderParserCallback<'_> {} -impl ParseCallbacks for DeriveAdderParserCallback<'_>{ - fn add_derives(&self, _name: &str) -> Vec{ - self.types_to_traits.get(_name).unwrap_or(&Vec::::new()).to_vec() +impl ParseCallbacks for DeriveAdderParserCallback<'_> { + fn add_derives(&self, _name: &str) -> Vec { + self.types_to_traits + .get(_name) + .unwrap_or(&Vec::::new()) + .to_vec() } -} \ No newline at end of file +} diff --git a/program/rust/src/c_oracle_header.rs b/program/rust/src/c_oracle_header.rs index 8073e46a4..5432e3e7b 100644 --- a/program/rust/src/c_oracle_header.rs +++ b/program/rust/src/c_oracle_header.rs @@ -5,7 +5,7 @@ #![allow(unused_variables)] #![allow(dead_code)] //All the custom trait imports should go here -use borsh::{BorshSerialize, BorshDeserialize}; +use borsh::{BorshDeserialize, BorshSerialize}; //bindings.rs is generated by build.rs to include //things defined in bindings.h -include!("../bindings.rs"); \ No newline at end of file +include!("../bindings.rs"); diff --git a/program/rust/src/lib.rs b/program/rust/src/lib.rs index 46884dc60..c4ebbc1c8 100644 --- a/program/rust/src/lib.rs +++ b/program/rust/src/lib.rs @@ -1,7 +1,6 @@ mod c_oracle_header; mod time_machine_types; - //Below is a high lever description of the rust/c setup. //As we migrate from C to Rust, our Rust code needs to be able to interract with C @@ -19,8 +18,7 @@ mod time_machine_types; //the only limitation of our set up is that we can not unit test in rust, anything that calls //a c function. Though we can test functions that use constants/types defined in oracle.h - -//do not link with C during unit tests (which are built in native architecture, unlike libpyth.o) +//do not link with C during unit tests (which are built in native architecture, unlike libpyth.o) #[cfg(target_arch = "bpf")] #[link(name = "cpyth")] extern "C" { @@ -42,4 +40,4 @@ pub extern "C" fn entrypoint(input: *mut u8) -> u64 { } else { return c_ret_val; } -} \ No newline at end of file +} From ec94b785a1a03d81e331fba88c6ffbb9067f03a6 Mon Sep 17 00:00:00 2001 From: Mark Jabbour Date: Fri, 22 Jul 2022 00:31:46 +0000 Subject: [PATCH 13/13] made it easier to add borsch to more types by not using vectors --- program/rust/build.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/program/rust/build.rs b/program/rust/build.rs index e7ab7dd65..e12cf262e 100644 --- a/program/rust/build.rs +++ b/program/rust/build.rs @@ -5,12 +5,13 @@ use std::vec::Vec; fn main() { println!("cargo:rustc-link-search=../c/target"); - let borsh_derives: Vec = - vec!["BorshSerialize".to_string(), "BorshDeserialize".to_string()]; + let borsh_derives = ["BorshSerialize".to_string(), "BorshDeserialize".to_string()]; //make a parser and to it type, traits pairs let mut parser = build_utils::DeriveAdderParserCallback::new(); - parser.register_traits("cmd_hdr", borsh_derives); + parser.register_traits("cmd_hdr", borsh_derives.to_vec()); + parser.register_traits("pc_acc", borsh_derives.to_vec()); + //generate and write bindings let bindings = Builder::default()