Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove pythnet feature flag #399

Merged
merged 13 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,7 @@ jobs:
run : |
docker create -ti --name container "${DOCKER_IMAGE}" bash
docker cp container:/home/pyth/pyth-client/target/pyth/pythnet/pyth_oracle_pythnet.so .
docker cp container:/home/pyth/pyth-client/target/pyth/solana/pyth_oracle_solana.so .
docker rm -f container

- name : Publish Solana binary
if : env.IS_ORACLE_RELEASE == 'true'
uses: svenstaro/upload-release-action@133984371c30d34e38222a64855679a414cb7575
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ./pyth_oracle_solana.so
asset_name: pyth_oracle_solana.so
tag: ${{ github.ref }}

- name : Publish Pythnet binary
if : env.IS_ORACLE_RELEASE == 'true'
Expand Down
45 changes: 20 additions & 25 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
files : program/
- id: end-of-file-fixer
files : program/
- id: check-added-large-files
- repo: local
hooks:
- id: cargo-fmt
name: Cargo Fmt
language: "rust"
entry: cargo +nightly-2023-03-01 fmt
pass_filenames: false
- id: cargo-clippy-solana
name: Cargo Clippy Solana
language: "rust"
entry : cargo +nightly-2023-03-01 clippy --tests --features check -- -D warnings
pass_filenames : false
- id: cargo-clippy-pythnet
name: Cargo Clippy Pythnet
language: "rust"
entry : cargo +nightly-2023-03-01 clippy --tests --features pythnet,check -- -D warnings
pass_filenames : false
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
files: program/
- id: end-of-file-fixer
files: program/
- id: check-added-large-files
- repo: local
hooks:
- id: cargo-fmt
name: Cargo Fmt
language: "rust"
entry: cargo +nightly-2023-03-01 fmt
pass_filenames: false
- id: cargo-clippy-pythnet
name: Cargo Clippy Pythnet
language: "rust"
entry: cargo +nightly-2023-03-01 clippy --tests --features check -- -D warnings
pass_filenames: false
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,10 @@ Finally, in docker extension inside VS Code click right and choose "Attach VS Co

Oracle program upgrades are managed by the Pythian Council multisig. The steps to deploy a new version are:

1. Create a release branch from `main`. This should include binaries for both the Solana mainnet and Pythnet oracle programs (`pyth_oracle_solana.so` and `pyth_oracle_pythnet.so`).
1. Create a release branch from `main`. This should include the binary for the Pythnet oracle program (`pyth_oracle_pythnet.so`).
2. [Install Solana CLI](https://docs.solana.com/cli/install-solana-cli-tools#use-solanas-install-tool) if not already installed.
3. Set Solana config for the target network, e.g., devnet: `solana config set --url https://api.devnet.solana.com`.
4. Execute `solana program write-buffer <ORACLE_PROGRAM_BINARY_FILENAME>` where `<ORACLE_PROGRAM_BINARY_FILENAME>` can be `pyth_oracle_solana.so` or `pyth_oracle_pythnet.so` to obtain the buffer address.
4. Execute `solana program write-buffer pyth_oracle_pythnet.so` to obtain the buffer address.
5. Run `solana program show <ORACLE_PROGRAM_PUBKEY>` to obtain the authority of the current program.
6. Use `solana program set-buffer-authority <BUFFER_PUBKEY> --new-buffer-authority <NEW_BUFFER_AUTHORITY>` to assign the upgrade authority from the previous step to the buffer address.
7. Submit a proposal with [`xc-admin`](https://github.com/pyth-network/pyth-crosschain/tree/main/governance/xc_admin/packages/xc_admin_cli) for program upgrade using the `upgrade-program` command.
Expand Down
9 changes: 1 addition & 8 deletions program/c/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,7 @@ else
include $(SOLANA)/sdk/sbf/c/sbf.mk
endif

# Propagate the PC_PYTHNET feature by conditionally defining it in a
# features.h header. The makefile included from Solana SDK does not
# have an easy way to pass extra C flags which motivates this approach.
ifdef PC_PYTHNET
FEATURES_H_BODY:="\#pragma once\n\#define PC_PYTHNET 1"
else
FEATURES_H_BODY:="\#pragma once"
endif
FEATURES_H_BODY:="\#pragma once"


.PHONY: features.h # Putting this in .PHONY makes sure the header is always regenerated
Expand Down
4 changes: 0 additions & 4 deletions program/c/src/oracle/native/upd_aggregate.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ char heap_start[8192];
#include "../upd_aggregate.h"
#include "../features.h"

#ifdef PC_PYTHNET
extern bool c_upd_aggregate_pythnet( pc_price_t *ptr, uint64_t slot, int64_t timestamp ){
#else
extern bool c_upd_aggregate_solana( pc_price_t *ptr, uint64_t slot, int64_t timestamp ){
#endif
return upd_aggregate(ptr, slot, timestamp );
}

Expand Down
49 changes: 36 additions & 13 deletions program/c/src/oracle/oracle.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,12 @@ extern "C" {
#define PC_MAP_TABLE_SIZE 640

// Total price component slots available
#define PC_NUM_COMP_SOLANA 32
#define PC_NUM_COMP_PYTHNET 128

// PC_NUM_COMP - number of price components in use
#ifdef PC_PYTHNET
// Not whole PC_NUM_COMP_PYTHNET because of stack issues appearing in upd_aggregate()
#define PC_NUM_COMP 64
#else
#define PC_NUM_COMP PC_NUM_COMP_SOLANA
#endif


#define PC_PROD_ACC_SIZE 512
#define PC_EXP_DECAY -9
Expand Down Expand Up @@ -209,20 +205,47 @@ typedef struct pc_price
pc_price_comp_t comp_[PC_NUM_COMP];// component prices
} pc_price_t;

#ifdef PC_PYTHNET

// Replace Solana component size's contribution with Pythnet's
#define PC_EXPECTED_PRICE_T_SIZE_PYTHNET (3312 \
- PC_NUM_COMP_SOLANA * sizeof(pc_price_comp_t) \
/*
The value 240 is derived from the fixed size of the pc_price_t struct excluding the size of the comp_ array.
Here is the breakdown of the sizes (in bytes) for each field within the pc_price_t struct:

- magic_ (uint32_t): 4 bytes
- ver_ (uint32_t): 4 bytes
- type_ (uint32_t): 4 bytes
- size_ (uint32_t): 4 bytes
- ptype_ (uint32_t): 4 bytes
- expo_ (int32_t): 4 bytes
- num_ (uint32_t): 4 bytes
- num_qt_ (uint32_t): 4 bytes
- last_slot_ (uint64_t): 8 bytes
- valid_slot_ (uint64_t): 8 bytes
- twap_ (pc_ema_t): 24 bytes (3 fields of int64_t each taking 8 bytes)
- twac_ (pc_ema_t): 24 bytes (similar to twap_)
- timestamp_ (int64_t): 8 bytes
- min_pub_ (uint8_t): 1 byte
- message_sent_ (int8_t): 1 byte
- max_latency_ (uint8_t): 1 byte
- drv3_ (int8_t): 1 byte
- drv4_ (int32_t): 4 bytes
- prod_ (pc_pub_key_t): 32 bytes (assuming pc_pub_key_t is a 32-byte array or struct)
- next_ (pc_pub_key_t): 32 bytes (similar to prod_)
- prev_slot_ (uint64_t): 8 bytes
- prev_price_ (int64_t): 8 bytes
- prev_conf_ (uint64_t): 8 bytes
- prev_timestamp_ (int64_t): 8 bytes
- agg_ (pc_price_info_t): 32 bytes

Adding up all these sizes gives us a total of 240 bytes for the fixed part of the pc_price_t struct.
The size of the comp_ array is variable and depends on PC_NUM_COMP, hence it is calculated separately and added to the base size of 240 bytes.
*/
#define PC_EXPECTED_PRICE_T_SIZE_PYTHNET (240 \
+ PC_NUM_COMP * sizeof(pc_price_comp_t) \
)

static_assert( sizeof( pc_price_t ) == PC_EXPECTED_PRICE_T_SIZE_PYTHNET, "" );
#undef PC_EXPECTED_PRICE_SIZE_PYTHNET
#undef PC_EXPECTED_PRICE_T_SIZE_PYTHNET
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems like a typo before


#else
static_assert( sizeof( pc_price_t ) == 3312, "" );
#endif

// This constant needs to be an upper bound of the price account size, it is used within pythd for ztsd.
// It is set tighly to the current price account + 96 component prices + 48 bytes for cumulative sums
Expand Down
6 changes: 1 addition & 5 deletions program/c/src/oracle/upd_aggregate.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@
#include "upd_aggregate.h"
#include "features.h"

// Dynamically deciding the name prevents linking the wrong C binary flavor
#ifdef PC_PYTHNET

extern bool c_upd_aggregate_pythnet( pc_price_t *ptr, uint64_t slot, int64_t timestamp ){
#else
extern bool c_upd_aggregate_solana( pc_price_t *ptr, uint64_t slot, int64_t timestamp ){
#endif
return upd_aggregate(ptr, slot, timestamp );
}

Expand Down
9 changes: 0 additions & 9 deletions program/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,11 @@ pythnet-sdk = { git = "https://github.com/pyth-network/pyth-crosschain", rev="60
serde_json = "1.0"
test-generator = "0.3.1"
csv = "1.1"
lazy_static = "1.4.0"

# IMPORTANT: Features which affect oracle business logic must be added
# to the `lazy_static` macro call in `pyth_simulator.rs`.
#
# Context: We perform a cargo-build-bpf call as part of running tests
# to obtain a BPF binary for testing. Desired features are not known
# to cargo-build-bpf at that point - we manually capture them at
# compile-time and pass on to the child process.
[features]
check = [] # Skips make build in build.rs, use with cargo-clippy and cargo-check
debug = []
library = []
pythnet = [] # logic-affecting features start with this one

[lib]
crate-type = ["cdylib", "lib"]
18 changes: 2 additions & 16 deletions program/rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use {
fn main() {
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();

let has_feat_pythnet = std::env::var("CARGO_FEATURE_PYTHNET").is_ok();
let has_feat_check = std::env::var("CARGO_FEATURE_CHECK").is_ok();

// OUT_DIR is the path cargo provides to a build directory under `target/` specifically for
Expand All @@ -25,17 +24,6 @@ fn main() {
eprintln!("OUT_DIR is {}", out_dir);
let out_dir = PathBuf::from(out_dir);

let mut make_extra_flags = vec![];
let mut clang_extra_flags = vec![];

if has_feat_pythnet {
// Define PC_PYTHNET for the C binary build
make_extra_flags.push("PC_PYTHNET=1");

// Define PC_PYTHNET for the bindings build
clang_extra_flags.push("-DPC_PYTHNET=1");
}

let mut make_targets = vec![];
if target_arch == "bpf" {
make_targets.push("cpyth-bpf");
Expand All @@ -51,7 +39,7 @@ fn main() {
if has_feat_check {
eprintln!("WARNING: `check` feature active, make build is skipped");
} else {
do_make_build(make_extra_flags, make_targets, &out_dir);
do_make_build(make_targets, &out_dir);

// Link against the right library for the architecture
if target_arch == "bpf" {
Expand All @@ -74,7 +62,6 @@ fn main() {
// Generate and write bindings
let bindings = Builder::default()
.clang_arg(format!("-I{:}", get_solana_inc_path().display()))
.clang_args(clang_extra_flags)
.header("./src/bindings.h")
.rustfmt_bindings(true)
.generate()
Expand All @@ -88,14 +75,13 @@ fn main() {
println!("cargo:rerun-if-changed=../");
}

fn do_make_build(extra_flags: Vec<&str>, targets: Vec<&str>, out_dir: &Path) {
fn do_make_build(targets: Vec<&str>, out_dir: &Path) {
// We must forward OUT_DIR as an env variable to the make script otherwise it will output
// its artifacts to the wrong place.
let make_output = std::process::Command::new("make")
.env("VERBOSE", "1")
.env("OUT_DIR", out_dir.display().to_string())
.current_dir("../c")
.args(extra_flags)
.args(targets)
.output()
.expect("Failed to run make for C oracle program");
Expand Down
4 changes: 1 addition & 3 deletions program/rust/src/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ mod product;
// Some types only exist during use as a library.
#[cfg(feature = "strum")]
pub use price::MessageType;
#[cfg(feature = "pythnet")]
pub use price::PriceCumulative;
#[cfg(test)]
pub use product::{
account_has_key_values,
Expand All @@ -56,6 +54,7 @@ pub use {
price::{
PriceAccount,
PriceComponent,
PriceCumulative,
PriceEma,
PriceInfo,
PythOracleSerialize,
Expand All @@ -72,7 +71,6 @@ pub use {
/// are authorized to perform certain administrative actions.
pub const PERMISSIONS_SEED: &str = "permissions";

#[cfg(feature = "pythnet")]
/// The update price instruction can optionally invoke another program via CPI. The
/// CPI will be signed with the PDA `[UPD_PRICE_WRITE_SEED, invoked_program_public_key]`
/// such that the caller can authenticate its origin.
Expand Down
Loading
Loading