Skip to content

feat: aggregate in the same slot #394

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

Merged
merged 61 commits into from
Apr 16, 2024
Merged
Changes from 1 commit
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
7523aa2
update aggregation logic to aggregate in the same slot
cctdaniel Feb 21, 2024
9c1ad0c
Add features.h to .gitignore
cctdaniel Feb 21, 2024
ce47715
Refactor test_upd_aggregate.rs: Clean up imports and formatting, upda…
cctdaniel Feb 21, 2024
2a2e2d8
add prev_twap_, prev_twac_ and prev_price_cumulative
cctdaniel Mar 13, 2024
e88c187
remove twap and twac from test_up_aggregate
cctdaniel Mar 14, 2024
2216b04
fix test_sizes
cctdaniel Mar 14, 2024
29403a9
fix borrow reference bug
cctdaniel Mar 14, 2024
3dfbc75
fix build
cctdaniel Mar 15, 2024
a756c22
fix logic
cctdaniel Mar 18, 2024
8922a9c
fix test_publish
cctdaniel Mar 19, 2024
760f5eb
format
cctdaniel Mar 19, 2024
dc2f0e7
fix test_publish_batch
cctdaniel Mar 19, 2024
89a8e7a
fix test_upd_price_no_fail_on_error
cctdaniel Mar 19, 2024
59359f2
fix test_upd_price_v2
cctdaniel Mar 19, 2024
b24cb44
fix logic
cctdaniel Mar 20, 2024
cb96cca
refactor
cctdaniel Mar 20, 2024
c0ddc28
update function desc
cctdaniel Mar 20, 2024
1605d94
fix logic
cctdaniel Mar 20, 2024
9b1b7e0
add comments
cctdaniel Mar 20, 2024
ddfc4ab
fix tests
cctdaniel Mar 20, 2024
e4c585e
add ema test
cctdaniel Mar 20, 2024
6bb795c
reduce PC_NUM_COMP_PYTHNET to 64
cctdaniel Mar 20, 2024
18912de
fix tests
cctdaniel Mar 21, 2024
9725869
add comments
cctdaniel Mar 21, 2024
26a07d5
revert to use PriceComponentArrayWrapper
cctdaniel Mar 21, 2024
42aadde
refactor
cctdaniel Mar 28, 2024
97f9fdf
Merge branch 'main' into same-slot-agg
cctdaniel Mar 28, 2024
05b5519
update c format
cctdaniel Mar 28, 2024
5817b1d
revert format
cctdaniel Mar 28, 2024
72196d8
revert format
cctdaniel Mar 28, 2024
dc91c22
gitignore .clang-format
cctdaniel Mar 28, 2024
563e170
remove clang-format
cctdaniel Mar 28, 2024
1f3eac9
revert format
cctdaniel Mar 28, 2024
1523216
revert format
cctdaniel Mar 28, 2024
4596c6e
format
cctdaniel Mar 28, 2024
11d6086
revert format
cctdaniel Mar 28, 2024
ac7508d
revert format
cctdaniel Mar 28, 2024
77cced8
fix comment
cctdaniel Apr 2, 2024
178a750
remove comment
cctdaniel Apr 2, 2024
caaecc1
add comment
cctdaniel Apr 2, 2024
5121d1d
refactor
cctdaniel Apr 2, 2024
b8f3484
add guard for first price update after deployment
cctdaniel Apr 3, 2024
f2c96f0
add back deleted test in test_publish
cctdaniel Apr 3, 2024
6bf147c
add tests for prev values to test_upd_price
cctdaniel Apr 3, 2024
7e53f79
update comment
cctdaniel Apr 3, 2024
149dec4
add test
cctdaniel Apr 3, 2024
0ff1061
use last_slot_ instead of agg_.pub_slot_
cctdaniel Apr 3, 2024
6000143
add more asserts
cctdaniel Apr 4, 2024
eeccb2a
remove crank again asserts
cctdaniel Apr 4, 2024
87ddfde
fix
cctdaniel Apr 4, 2024
c976989
address comments
cctdaniel Apr 8, 2024
404f012
address comments
cctdaniel Apr 8, 2024
7aa7f94
remove print statement
cctdaniel Apr 8, 2024
144bf94
add test to simulate program upgrade
cctdaniel Apr 8, 2024
6b539db
refactor
cctdaniel Apr 9, 2024
5be3e09
address comments
cctdaniel Apr 10, 2024
458f143
address comments
cctdaniel Apr 15, 2024
49cf2b9
address comments
cctdaniel Apr 15, 2024
490e658
address comments
cctdaniel Apr 15, 2024
0d404c3
merge test_upd_price with test_upd_price_v2
cctdaniel Apr 15, 2024
9c3a9a7
add asserts
cctdaniel Apr 16, 2024
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
5 changes: 1 addition & 4 deletions program/rust/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -19,13 +19,10 @@ mod test_publish_batch;
mod test_set_max_latency;
mod test_set_min_pub;
mod test_sizes;
mod test_twap;
mod test_upd_aggregate;
mod test_upd_permissions;
mod test_upd_price;
mod test_upd_price_no_fail_on_error;
mod test_upd_product;
mod test_utils;


mod test_twap;
mod test_upd_price_v2;
151 changes: 146 additions & 5 deletions program/rust/src/tests/test_upd_price.rs
Original file line number Diff line number Diff line change
@@ -88,6 +88,9 @@ fn test_upd_price() {
assert_eq!(price_data.prev_price_, 0);
assert_eq!(price_data.prev_conf_, 0);
assert_eq!(price_data.prev_timestamp_, 0);
assert_eq!(price_data.price_cumulative.price, 42);
assert_eq!(price_data.price_cumulative.conf, 2);
assert_eq!(price_data.price_cumulative.num_down_slots, 0);
}

// add some prices for current slot - get rejected
@@ -121,6 +124,9 @@ fn test_upd_price() {
assert_eq!(price_data.prev_price_, 0);
assert_eq!(price_data.prev_conf_, 0);
assert_eq!(price_data.prev_timestamp_, 0);
assert_eq!(price_data.price_cumulative.price, 42);
assert_eq!(price_data.price_cumulative.conf, 2);
assert_eq!(price_data.price_cumulative.num_down_slots, 0);
}

// update new price in new slot, aggregate should be updated and prev values should be updated
@@ -153,6 +159,9 @@ fn test_upd_price() {
assert_eq!(price_data.prev_price_, 42);
assert_eq!(price_data.prev_conf_, 2);
assert_eq!(price_data.prev_timestamp_, 1);
assert_eq!(price_data.price_cumulative.price, 42 + 2 * 81);
assert_eq!(price_data.price_cumulative.conf, 3 * 2);
assert_eq!(price_data.price_cumulative.num_down_slots, 0);
}

// next price doesn't change but slot and timestamp does
@@ -186,6 +195,9 @@ fn test_upd_price() {
assert_eq!(price_data.prev_conf_, 2);
assert_eq!(price_data.timestamp_, 4); // We only check for timestamp_ here because test_upd_price doesn't directly update timestamp_, this is updated through c_upd_aggregate which is tested in test_upd_aggregate, but we assert here to show that in subsequent asserts for prev_timestamp_ the value should be updated to this value
assert_eq!(price_data.prev_timestamp_, 1);
assert_eq!(price_data.price_cumulative.price, 42 + 3 * 81);
assert_eq!(price_data.price_cumulative.conf, 4 * 2);
assert_eq!(price_data.price_cumulative.num_down_slots, 0);
}

// next price doesn't change and neither does aggregate but slot does
@@ -217,6 +229,9 @@ fn test_upd_price() {
assert_eq!(price_data.prev_price_, 81);
assert_eq!(price_data.prev_conf_, 2);
assert_eq!(price_data.prev_timestamp_, 4);
assert_eq!(price_data.price_cumulative.price, 42 + 81 * 4);
assert_eq!(price_data.price_cumulative.conf, 5 * 2);
assert_eq!(price_data.price_cumulative.num_down_slots, 0);
}

// try to publish back-in-time
@@ -250,6 +265,9 @@ fn test_upd_price() {
assert_eq!(price_data.prev_price_, 81);
assert_eq!(price_data.prev_conf_, 2);
assert_eq!(price_data.prev_timestamp_, 4);
assert_eq!(price_data.price_cumulative.price, 42 + 81 * 4);
assert_eq!(price_data.price_cumulative.conf, 5 * 2);
assert_eq!(price_data.price_cumulative.num_down_slots, 0);
}

populate_instruction(&mut instruction_data, 50, 20, 5);
@@ -289,6 +307,9 @@ fn test_upd_price() {
assert_eq!(price_data.prev_price_, 81);
assert_eq!(price_data.prev_conf_, 2);
assert_eq!(price_data.prev_timestamp_, 4);
assert_eq!(price_data.price_cumulative.price, 42 + 81 * 4);
assert_eq!(price_data.price_cumulative.conf, 2 * 5);
assert_eq!(price_data.price_cumulative.num_down_slots, 0);
}

// Negative prices are accepted
@@ -320,13 +341,16 @@ fn test_upd_price() {
assert_eq!(price_data.prev_price_, 81);
assert_eq!(price_data.prev_conf_, 2);
assert_eq!(price_data.prev_timestamp_, 4);
assert_eq!(price_data.price_cumulative.price, 42 + 81 * 4 - 100 * 3);
assert_eq!(price_data.price_cumulative.conf, 2 * 5 + 3); // 2 * 5 + 1 * 3
assert_eq!(price_data.price_cumulative.num_down_slots, 0);
}

// add new test for multiple publishers and ensure that agg price is not updated multiple times when program upgrade happens in the same slot after the first update
let mut funding_setup_two = AccountSetup::new_funding();
let funding_account_two = funding_setup_two.as_account_info();

add_publisher(&mut price_account, funding_account_two.key, 1);
add_publisher(&mut price_account, funding_account_two.key);

populate_instruction(&mut instruction_data, 10, 1, 10);
update_clock_slot(&mut clock_account, 10);
@@ -359,7 +383,12 @@ fn test_upd_price() {
assert_eq!(price_data.prev_timestamp_, 4);
assert_eq!(price_data.twap_.numer_, 1677311098);
assert_eq!(price_data.twap_.denom_, 1279419481);
assert_eq!(price_data.price_cumulative.price, 86);
assert_eq!(
price_data.price_cumulative.price,
42 + 81 * 4 - 100 * 3 + 10 * 2
);
assert_eq!(price_data.price_cumulative.conf, 2 * 5 + 5); // 2 * 5 + 1 * 5
assert_eq!(price_data.price_cumulative.num_down_slots, 0);
}

// reset twap_.denom_ to 0 to simulate program upgrade in the same slot and make sure agg_.price_ is not updated again
@@ -396,7 +425,111 @@ fn test_upd_price() {
assert_eq!(price_data.prev_timestamp_, 4);
assert_eq!(price_data.twap_.numer_, 1677311098); // twap_.numer_ should not be updated
assert_eq!(price_data.twap_.denom_, 1279419481); // twap_.denom_ should not be updated
assert_eq!(price_data.price_cumulative.price, 86); // price_cumulative should not be updated

// price_cumulative should not be updated
assert_eq!(
price_data.price_cumulative.price,
42 + 81 * 4 - 100 * 3 + 10 * 2
);
assert_eq!(price_data.price_cumulative.conf, 2 * 5 + 5);
assert_eq!(price_data.price_cumulative.num_down_slots, 0);
}

remove_publisher(&mut price_account);
// Big gap
populate_instruction(&mut instruction_data, 60, 4, 50);
update_clock_slot(&mut clock_account, 50);

assert!(process_instruction(
&program_id,
&[
funding_account.clone(),
price_account.clone(),
clock_account.clone()
],
&instruction_data
)
.is_ok());

{
let price_data = load_checked::<PriceAccount>(&price_account, PC_VERSION).unwrap();
assert_eq!(price_data.comp_[0].latest_.price_, 60);
assert_eq!(price_data.comp_[0].latest_.conf_, 4);
assert_eq!(price_data.comp_[0].latest_.pub_slot_, 50);
assert_eq!(price_data.comp_[0].latest_.status_, PC_STATUS_TRADING);
assert_eq!(price_data.valid_slot_, 10);
assert_eq!(price_data.agg_.pub_slot_, 50);
assert_eq!(price_data.agg_.price_, 60);
assert_eq!(price_data.agg_.conf_, 4);
assert_eq!(price_data.agg_.status_, PC_STATUS_TRADING);
assert_eq!(
price_data.price_cumulative.price,
42 + 81 * 4 - 100 * 3 + 10 * 2 + 60 * 40
);
assert_eq!(price_data.price_cumulative.conf, 2 * 5 + 5 + 40 * 4);
assert_eq!(price_data.price_cumulative.num_down_slots, 15);
}

// add new test for multiple publishers and ensure that price_cumulative is updated correctly
add_publisher(&mut price_account, funding_account_two.key);
populate_instruction(&mut instruction_data, 10, 1, 100);
update_clock_slot(&mut clock_account, 100);
assert!(process_instruction(
&program_id,
&[
funding_account.clone(),
price_account.clone(),
clock_account.clone()
],
&instruction_data
)
.is_ok());

populate_instruction(&mut instruction_data, 20, 2, 100);
assert!(process_instruction(
&program_id,
&[
funding_account_two.clone(),
price_account.clone(),
clock_account.clone()
],
&instruction_data
)
.is_ok());

{
let price_data = load_checked::<PriceAccount>(&price_account, PC_VERSION).unwrap();
assert_eq!(price_data.comp_[0].latest_.price_, 10);
assert_eq!(price_data.comp_[0].latest_.conf_, 1);
assert_eq!(price_data.comp_[0].latest_.pub_slot_, 100);
assert_eq!(price_data.comp_[0].latest_.status_, PC_STATUS_TRADING);
assert_eq!(price_data.comp_[1].latest_.price_, 20);
assert_eq!(price_data.comp_[1].latest_.conf_, 2);
assert_eq!(price_data.comp_[1].latest_.pub_slot_, 100);
assert_eq!(price_data.comp_[1].latest_.status_, PC_STATUS_TRADING);
assert_eq!(price_data.valid_slot_, 100);
assert_eq!(price_data.agg_.pub_slot_, 100);
assert_eq!(price_data.agg_.price_, 14);
assert_eq!(price_data.agg_.conf_, 6);
assert_eq!(price_data.agg_.status_, PC_STATUS_TRADING);
assert_eq!(price_data.prev_slot_, 50);
assert_eq!(price_data.prev_price_, 60);
assert_eq!(price_data.prev_conf_, 4);
assert_eq!(
price_data.prev_price_cumulative.price,
42 + 81 * 4 - 100 * 3 + 10 * 2 + 60 * 40
);
assert_eq!(price_data.prev_price_cumulative.conf, 2 * 5 + 5 + 40 * 4);
assert_eq!(price_data.prev_price_cumulative.num_down_slots, 15);
assert_eq!(
price_data.price_cumulative.price,
42 + 81 * 4 - 100 * 3 + 10 * 2 + 60 * 40 + 14 * 50
); // (42 + 81 * 4 - 100 * 3 + 10 * 2 + 60 * 40 + 55) is the price cumulative from the previous test and 14 * 49 (slot_gap) is the price cumulative from this test
assert_eq!(
price_data.price_cumulative.conf,
2 * 5 + 5 + 40 * 4 + 6 * 50
);
assert_eq!(price_data.price_cumulative.num_down_slots, 40); // prev num_down_slots was 15 and since pub slot is 100 and last pub slot was 50, slot_gap is 50 and default latency is 25, so num_down_slots = 50 - 25 = 25, so total num_down_slots = 15 + 25 = 40
}
}

@@ -411,8 +544,16 @@ fn populate_instruction(instruction_data: &mut [u8], price: i64, conf: u64, pub_
cmd.unused_ = 0;
}

fn add_publisher(price_account: &mut AccountInfo, publisher_key: &Pubkey, index: usize) {
fn add_publisher(price_account: &mut AccountInfo, publisher_key: &Pubkey) {
let mut price_data = load_checked::<PriceAccount>(price_account, PC_VERSION).unwrap();
price_data.num_ = (index + 1) as u32;
let index = price_data.num_ as usize;
price_data.comp_[index].pub_ = *publisher_key;
price_data.num_ += 1;
}

fn remove_publisher(price_account: &mut AccountInfo) {
let mut price_data = load_checked::<PriceAccount>(price_account, PC_VERSION).unwrap();
if price_data.num_ > 0 {
price_data.num_ -= 1;
}
}
518 changes: 0 additions & 518 deletions program/rust/src/tests/test_upd_price_v2.rs

This file was deleted.