Explorar o código

doc(target_chains/solana): add more comments and configure publish (#1883)

Pavel Strakhov hai 1 ano
pai
achega
e08410b4e5

+ 24 - 0
.github/workflows/publish-pyth-price-publisher.yml

@@ -0,0 +1,24 @@
+name: Publish Pyth Price Publisher to crates.io
+
+on:
+  push:
+    tags:
+      - pyth-price-publisher-v*
+jobs:
+  publish-pyth-price-publisher:
+    name: Publish Pyth Price Publisher
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout sources
+        uses: actions/checkout@v2
+      - name: Install Rust
+        uses: actions-rs/toolchain@v1
+        with:
+          toolchain: stable
+          default: true
+          profile: minimal
+      - name: Publish
+        run: cargo publish --token ${CARGO_REGISTRY_TOKEN}
+        env:
+          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
+        working-directory: "target_chains/solana/programs/pyth-price-publisher"

+ 12 - 4
target_chains/solana/programs/pyth-price-publisher/src/accounts/buffer.rs

@@ -85,10 +85,13 @@ impl BufferedPrice {
     }
 }
 
+/// Verifies the account magic.
 pub fn format_matches(data: &[u8]) -> bool {
     super::format(data).map_or(false, |f| f == FORMAT)
 }
 
+/// Verifies the account size and header. Returns the header and the currently stored prices
+/// (as indicated by the `num_prices` field in the header).
 pub fn read(data: &[u8]) -> Result<(&BufferHeader, &[BufferedPrice]), ReadAccountError> {
     if data.len() < size_of::<BufferHeader>() {
         return Err(ReadAccountError::DataTooShort);
@@ -109,10 +112,13 @@ pub fn read(data: &[u8]) -> Result<(&BufferHeader, &[BufferedPrice]), ReadAccoun
     Ok((header, prices))
 }
 
+/// Returns the buffer size required to hold the specified number of prices.
 pub fn size(max_prices: usize) -> usize {
     size_of::<BufferHeader>() + max_prices * size_of::<BufferedPrice>()
 }
 
+/// Verifies the account size and header. Returns the header and the remaining buffer space.
+/// The remaining space may contain some prices, as indicated by the `num_prices` field in the header.
 pub fn read_mut(data: &mut [u8]) -> Result<(&mut BufferHeader, &mut [u8]), ReadAccountError> {
     if data.len() < size_of::<BufferHeader>() {
         return Err(ReadAccountError::DataTooShort);
@@ -125,6 +131,7 @@ pub fn read_mut(data: &mut [u8]) -> Result<(&mut BufferHeader, &mut [u8]), ReadA
     Ok((header, prices))
 }
 
+/// Initializes the buffer. Returns the header and the remaining buffer space.
 pub fn create(
     data: &mut [u8],
     publisher: [u8; 32],
@@ -141,7 +148,8 @@ pub fn create(
     Ok((header, prices))
 }
 
-pub fn extend(
+/// Removes prices for the other slot from the buffer (if any) and adds new prices.
+pub fn update(
     header: &mut BufferHeader,
     prices: &mut [u8],
     current_slot: u64,
@@ -193,17 +201,17 @@ fn test_extend_clears_old_prices() {
     assert!(read(&buf).unwrap().1.is_empty());
     {
         let (header, prices) = read_mut(&mut buf).unwrap();
-        extend(header, prices, 1, &vec![1; 40]).unwrap();
+        update(header, prices, 1, &vec![1; 40]).unwrap();
     }
     assert_eq!(read(&buf).unwrap().1.len(), 2);
     {
         let (header, prices) = read_mut(&mut buf).unwrap();
-        extend(header, prices, 1, &vec![1; 60]).unwrap();
+        update(header, prices, 1, &vec![1; 60]).unwrap();
     }
     assert_eq!(read(&buf).unwrap().1.len(), 5);
     {
         let (header, prices) = read_mut(&mut buf).unwrap();
-        extend(header, prices, 2, &vec![1; 60]).unwrap();
+        update(header, prices, 2, &vec![1; 60]).unwrap();
     }
     assert_eq!(read(&buf).unwrap().1.len(), 3);
 }

+ 4 - 2
target_chains/solana/programs/pyth-price-publisher/src/processor/initialize.rs

@@ -22,8 +22,10 @@ use {
     },
 };
 
-// Creates a config account that stores the authority pubkey.
-// The authority is allowed to modify publisher configs.
+/// Creates a config account that stores the authority pubkey.
+/// The authority is the account that will be allowed to modify publisher configs.
+/// See `Instruction` for the list of required accounts.
+/// The config account must be a non-existing PDA account with an expected seed.
 pub fn initialize(
     program_id: &Pubkey,
     accounts: &[AccountInfo],

+ 13 - 2
target_chains/solana/programs/pyth-price-publisher/src/processor/initialize_publisher.rs

@@ -29,8 +29,19 @@ use {
     },
 };
 
-// Creates a publisher config account and stores the buffer account pubkey in it.
-// Verifies and initializes the buffer account.
+/// Creates a publisher config account and stores the buffer account pubkey in it.
+/// Verifies and initializes the buffer account.
+/// See `Instruction` for the list of required accounts.
+/// The config account must be an initialized PDA account with an expected seed.
+/// The authority account that signed the instruction
+/// must match the authority key stored in the config account.
+/// The publisher config account must be a non-existing PDA account with an expected seed.
+/// The buffer config must be an existing, zero-filled account owned by the program.
+/// Note: we aren't using a PDA for the buffer because the program can't create
+/// a PDA larger than 10240 bytes in a single transaction.
+/// Note: currently, the publisher config can only be set once and can only contain
+/// a single buffer key. If we need to modify the buffer key or create multiple buffer keys
+/// per publisher, we'll need to upgrade the program.
 pub fn initialize_publisher(
     program_id: &Pubkey,
     accounts: &[AccountInfo],

+ 5 - 1
target_chains/solana/programs/pyth-price-publisher/src/processor/submit_prices.rs

@@ -27,6 +27,10 @@ use {
 /// its buffer account. The buffer account will be read and applied by the validator
 /// to read at the end of the slot.
 /// If there are old prices in the account, they will be removed before adding new data.
+/// See `Instruction` for the list of required accounts.
+/// The publisher config account must be an initialized PDA account with an expected seed
+/// (depending on the publisher account that signed the instruction).
+/// The buffer account must match the buffer key stored in the publisher config account.
 pub fn submit_prices(
     program_id: &Pubkey,
     accounts: &[AccountInfo],
@@ -54,7 +58,7 @@ pub fn submit_prices(
     // Access and update PublisherPrices account with new data.
     let mut buffer_data = buffer.data.borrow_mut();
     let (header, prices) = buffer::read_mut(*buffer_data)?;
-    buffer::extend(header, prices, Clock::get()?.slot, prices_data)?;
+    buffer::update(header, prices, Clock::get()?.slot, prices_data)?;
 
     Ok(())
 }