|
|
@@ -90,6 +90,7 @@ async fn test_multiple_resize_buffer_ixs_in_same_txn() {
|
|
|
}
|
|
|
|
|
|
#[tokio::test]
|
|
|
+#[should_panic]
|
|
|
async fn fail_resize_buffer_invalid_increase() {
|
|
|
let mut context = MessageBufferTestContext::initialize_with_default_test_buffer(
|
|
|
false,
|
|
|
@@ -111,7 +112,6 @@ async fn fail_resize_buffer_invalid_increase() {
|
|
|
let resize_ix = resize_msg_buffer_ix(
|
|
|
cpi_caller_auth,
|
|
|
pyth_price_acct,
|
|
|
- msg_buffer_bump,
|
|
|
target_size,
|
|
|
whitelist,
|
|
|
admin.pubkey(),
|
|
|
@@ -125,16 +125,173 @@ async fn fail_resize_buffer_invalid_increase() {
|
|
|
let err: ProgramError = res.unwrap_err().into();
|
|
|
assert_eq!(
|
|
|
err,
|
|
|
- ProgramError::Custom(MessageBufferError::TargetSizeDeltaExceeded.into())
|
|
|
+ ProgramError::Custom(anchor_lang::error::ErrorCode::AccountReallocExceedsLimit.into())
|
|
|
);
|
|
|
|
|
|
|
|
|
- // shrink buffer size to less than minimum allowed
|
|
|
- let target_size = 1;
|
|
|
+ let msg_buffer_account_data = context
|
|
|
+ .fetch_msg_buffer_account_data(&msg_buffer_pda)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+
|
|
|
+ assert_eq!(
|
|
|
+ msg_buffer_account_data.len(),
|
|
|
+ MessageBufferTestContext::DEFAULT_TARGET_SIZE as usize
|
|
|
+ );
|
|
|
+
|
|
|
+ let (bump, _version, _header_len, end_offsets) =
|
|
|
+ deserialize_msg_buffer_header(&msg_buffer_account_data);
|
|
|
+
|
|
|
+ assert_eq!(bump, msg_buffer_bump);
|
|
|
+ assert_eq!(end_offsets, [0u16; 255]);
|
|
|
+
|
|
|
+ // shrink buffer size to less than MessageBuffer::HEADER_LEN
|
|
|
+ let target_size = 15;
|
|
|
+ let resize_ix = resize_msg_buffer_ix(
|
|
|
+ cpi_caller_auth,
|
|
|
+ pyth_price_acct,
|
|
|
+ target_size,
|
|
|
+ whitelist,
|
|
|
+ admin.pubkey(),
|
|
|
+ msg_buffer_pda,
|
|
|
+ );
|
|
|
+
|
|
|
+ // a target_size less than the MessageBuffer::HEADER_LEN
|
|
|
+ // will result in a `ProgramFailedToComplete` (or AccountDiscriminatorNotFound
|
|
|
+ // if target_size < 8) since after the realloc,
|
|
|
+ // the AccountLoadder.load/load_mut() calls will fail
|
|
|
+ context
|
|
|
+ .process_ixs(&[resize_ix], vec![&admin])
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+}
|
|
|
+
|
|
|
+#[tokio::test]
|
|
|
+async fn test_resize_initialized_buffer() {
|
|
|
+ let mut context = MessageBufferTestContext::initialize_with_default_test_buffer(
|
|
|
+ false,
|
|
|
+ MessageBufferTestContext::DEFAULT_TARGET_SIZE,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ let payer = context.payer.pubkey();
|
|
|
+
|
|
|
+ let whitelist = context.whitelist();
|
|
|
+ let cpi_caller_auth = MessageBufferTestContext::get_mock_cpi_auth();
|
|
|
+ let (msg_buffer_pda, msg_buffer_bump) = MessageBufferTestContext::default_msg_buffer();
|
|
|
+
|
|
|
+ let add_price_params = MessageBufferTestContext::DEFAULT_ADD_PRICE_PARAMS;
|
|
|
+ context
|
|
|
+ .add_price(add_price_params, payer, whitelist, cpi_caller_auth)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ let (id, price, price_expo, ema, ema_expo) = add_price_params;
|
|
|
+
|
|
|
+ let msg_buffer_account_data = context
|
|
|
+ .fetch_msg_buffer_account_data(&msg_buffer_pda)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+
|
|
|
+ let (bump, _version, header_len, end_offsets) =
|
|
|
+ deserialize_msg_buffer_header(&msg_buffer_account_data);
|
|
|
+
|
|
|
+ assert_eq!(bump, msg_buffer_bump);
|
|
|
+ // size_of(price::MessageHeader) + FullPriceMessage::SIZE
|
|
|
+ let msg_size_0 = 7 + 40;
|
|
|
+ assert_eq!(&end_offsets[0], &msg_size_0);
|
|
|
+
|
|
|
+ // size_of(price::MessageHeader) + CompactPriceMessage::SIZE
|
|
|
+ let msg_size_1 = 7 + 24;
|
|
|
+ assert_eq!(&end_offsets[1], &(msg_size_0 + msg_size_1));
|
|
|
+
|
|
|
+ assert_eq!(&end_offsets[2..], &[0u16; 253]);
|
|
|
+
|
|
|
+ let msgs = extract_msg_buffer_messages(header_len, end_offsets, &msg_buffer_account_data);
|
|
|
+ validate_price_msgs(id, price, price_expo, ema, ema_expo, &msgs).unwrap();
|
|
|
+
|
|
|
+
|
|
|
+ // increase buffer size should not edit the original data
|
|
|
+ let target_size = MessageBufferTestContext::DEFAULT_TARGET_SIZE + 10240;
|
|
|
+ let target_sizes = vec![target_size];
|
|
|
+ context
|
|
|
+ .resize_msg_buffer(
|
|
|
+ MessageBufferTestContext::DEFAULT_TEST_PRICE_ID,
|
|
|
+ target_sizes,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+
|
|
|
+ let msg_buffer_account_data = context
|
|
|
+ .fetch_msg_buffer_account_data(&msg_buffer_pda)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ let (bump, _version, header_len, end_offsets) =
|
|
|
+ deserialize_msg_buffer_header(&msg_buffer_account_data);
|
|
|
+
|
|
|
+ assert_eq!(bump, msg_buffer_bump);
|
|
|
+ // size_of(price::MessageHeader) + FullPriceMessage::SIZE
|
|
|
+ let msg_size_0 = 7 + 40;
|
|
|
+ assert_eq!(&end_offsets[0], &msg_size_0);
|
|
|
+
|
|
|
+ // size_of(price::MessageHeader) + CompactPriceMessage::SIZE
|
|
|
+ let msg_size_1 = 7 + 24;
|
|
|
+ assert_eq!(&end_offsets[1], &(msg_size_0 + msg_size_1));
|
|
|
+
|
|
|
+ assert_eq!(&end_offsets[2..], &[0u16; 253]);
|
|
|
+
|
|
|
+ let msgs = extract_msg_buffer_messages(header_len, end_offsets, &msg_buffer_account_data);
|
|
|
+ validate_price_msgs(id, price, price_expo, ema, ema_expo, &msgs).unwrap();
|
|
|
+}
|
|
|
+
|
|
|
+#[tokio::test]
|
|
|
+async fn fail_resize_initialized_buffer() {
|
|
|
+ let mut context = MessageBufferTestContext::initialize_with_default_test_buffer(
|
|
|
+ false,
|
|
|
+ MessageBufferTestContext::DEFAULT_TARGET_SIZE,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ let payer = context.payer.pubkey();
|
|
|
+ let admin = context.default_admin();
|
|
|
+ let pyth_price_acct = MessageBufferTestContext::default_pyth_price_account();
|
|
|
+ let whitelist = context.whitelist();
|
|
|
+ let cpi_caller_auth = MessageBufferTestContext::get_mock_cpi_auth();
|
|
|
+ let (msg_buffer_pda, _msg_buffer_bump) = MessageBufferTestContext::default_msg_buffer();
|
|
|
+
|
|
|
+ let add_price_params = MessageBufferTestContext::DEFAULT_ADD_PRICE_PARAMS;
|
|
|
+ context
|
|
|
+ .add_price(add_price_params, payer, whitelist, cpi_caller_auth)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+
|
|
|
+ let msg_buffer_account_data = context
|
|
|
+ .fetch_msg_buffer_account_data(&msg_buffer_pda)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+
|
|
|
+ let (_, _version, header_len, end_offsets) =
|
|
|
+ deserialize_msg_buffer_header(&msg_buffer_account_data);
|
|
|
+
|
|
|
+ let max_end_offset = end_offsets.iter().max().unwrap();
|
|
|
+ let min_size = header_len + max_end_offset;
|
|
|
+
|
|
|
+
|
|
|
+ // decrease buffer size to less than something that can fit the current messages
|
|
|
+ let target_size = (min_size as u32) - 1;
|
|
|
+
|
|
|
+
|
|
|
let resize_ix = resize_msg_buffer_ix(
|
|
|
cpi_caller_auth,
|
|
|
pyth_price_acct,
|
|
|
- msg_buffer_bump,
|
|
|
target_size,
|
|
|
whitelist,
|
|
|
admin.pubkey(),
|
|
|
@@ -144,13 +301,32 @@ async fn fail_resize_buffer_invalid_increase() {
|
|
|
let res = context.process_ixs(&[resize_ix], vec![&admin]).await;
|
|
|
|
|
|
assert!(res.is_err());
|
|
|
+
|
|
|
let err: ProgramError = res.unwrap_err().into();
|
|
|
assert_eq!(
|
|
|
err,
|
|
|
ProgramError::Custom(MessageBufferError::MessageBufferTooSmall.into())
|
|
|
);
|
|
|
-}
|
|
|
|
|
|
-#[tokio::test]
|
|
|
-async fn test_resize_initialized_buffer() {
|
|
|
+ let target_size = (min_size as u32) + 1;
|
|
|
+
|
|
|
+
|
|
|
+ let resize_ix = resize_msg_buffer_ix(
|
|
|
+ cpi_caller_auth,
|
|
|
+ pyth_price_acct,
|
|
|
+ target_size,
|
|
|
+ whitelist,
|
|
|
+ admin.pubkey(),
|
|
|
+ msg_buffer_pda,
|
|
|
+ );
|
|
|
+
|
|
|
+ let res = context.process_ixs(&[resize_ix], vec![&admin]).await;
|
|
|
+
|
|
|
+ assert!(res.is_ok());
|
|
|
+ let msg_buffer_account_data = context
|
|
|
+ .fetch_msg_buffer_account_data(&msg_buffer_pda)
|
|
|
+ .await
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ assert_eq!(msg_buffer_account_data.len(), target_size as usize);
|
|
|
}
|