Skip to content

Commit edf8567

Browse files
authored
include permissions account in instructions (#42)
* delete oracle file from git * include permissions account in instructions update tests download latest oracle for tests * bump app version, update poetry version * update solana version * add pydoc * run poetry lock * linting * remove ecr build * remove useless if-else
1 parent 622998e commit edf8567

File tree

16 files changed

+1081
-1168
lines changed

16 files changed

+1081
-1168
lines changed

.github/actions/python-poetry/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ inputs:
99
poetry-version:
1010
required: false
1111
description: Poetry version
12-
default: "1.3.2"
12+
default: "1.8.2"
1313

1414
runs:
1515
using: composite

.github/workflows/ci.yaml

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,41 +20,9 @@ jobs:
2020
steps:
2121
- uses: actions/checkout@v2
2222
- uses: ./.github/actions/python-poetry
23-
- run: sh -c "$(curl -sSfL https://release.solana.com/v1.10.35/install)"
23+
- run: sh -c "$(curl -sSfL https://release.solana.com/v1.18.17/install)"
2424
- run: echo "$HOME/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH
2525
- run: poetry run pytest
2626
env:
2727
TEST_MODE: "1"
2828
DEV_MODE: "1"
29-
build-and-push-ecr:
30-
runs-on: ubuntu-latest
31-
needs: [run-tests]
32-
permissions:
33-
id-token: write
34-
contents: read
35-
steps:
36-
- uses: actions/checkout@v2
37-
- uses: aws-actions/[email protected]
38-
with:
39-
role-to-assume: arn:aws:iam::192824654885:role/github-actions-ecr
40-
aws-region: eu-west-2
41-
- uses: docker/login-action@v2
42-
with:
43-
registry: public.ecr.aws
44-
env:
45-
AWS_REGION: us-east-1
46-
- run: docker context create builders
47-
- uses: docker/setup-buildx-action@v2
48-
with:
49-
version: latest
50-
endpoint: builders
51-
- uses: haya14busa/action-cond@v1
52-
id: image_tag
53-
with:
54-
cond: ${{ startsWith(github.ref, 'refs/tags/') }}
55-
if_true: ${{ github.ref_name }}
56-
if_false: ${{ github.sha }}
57-
- uses: docker/build-push-action@v2
58-
with:
59-
push: true
60-
tags: public.ecr.aws/pyth-network/${{ github.event.repository.name }}:${{ steps.image_tag.outputs.value }}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
__pycache__
44
dist
55
keys
6+
pyth_oracle.so
67
permissions.json
78
products.json
89
publishers.json
910
test-ledger
11+
.tool-versions
1012

1113
# IntelliJ files
1214
.idea

.pre-commit-config.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ repos:
1010
entry: poetry run black .
1111
pass_filenames: false
1212
language: system
13-
- id: mypy
14-
name: mypy
15-
entry: poetry run mypy program_admin/ tests/
13+
- id: pyright
14+
name: pyright
15+
entry: poetry run pyright program_admin/ tests/
1616
pass_filenames: false
1717
language: system
18-
- id: pylint
19-
name: pylint
20-
entry: poetry run pylint program_admin/ tests/
18+
- id: pyflakes
19+
name: pyflakes
20+
entry: poetry run pyflakes program_admin/ tests/
2121
pass_filenames: false
2222
language: system

Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
lint:
2+
poetry run isort --profile=black program_admin/ tests/
3+
poetry run black program_admin/ tests/
4+
poetry run pyright program_admin/ tests/
5+
poetry run pyflakes program_admin/ tests/
6+
7+
install:
8+
poetry install
9+
10+
test:
11+
poetry run pytest

poetry.lock

Lines changed: 870 additions & 1020 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

program_admin/__init__.py

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import json
22
import os
3-
import sys
4-
from dataclasses import asdict
53
from pathlib import Path
6-
from typing import Any, Dict, List, Literal, Optional, Tuple
4+
from typing import Dict, List, Literal, Optional, Tuple
75

86
from loguru import logger
97
from solana import system_program
@@ -16,13 +14,7 @@
1614

1715
from program_admin import instructions as pyth_program
1816
from program_admin.keys import load_keypair
19-
from program_admin.parsing import (
20-
parse_account,
21-
parse_overrides_json,
22-
parse_permissions_json,
23-
parse_products_json,
24-
parse_publishers_json,
25-
)
17+
from program_admin.parsing import parse_account
2618
from program_admin.types import (
2719
Network,
2820
PythAuthorityPermissionAccount,
@@ -72,7 +64,7 @@ def __init__(
7264
key_dir: str,
7365
program_key: str,
7466
commitment: Literal["confirmed", "finalized"],
75-
rpc_endpoint: str = None,
67+
rpc_endpoint: str = "",
7668
):
7769
self.network = network
7870
self.rpc_endpoint = rpc_endpoint or RPC_ENDPOINTS[network]
@@ -223,10 +215,10 @@ async def send_transaction(
223215

224216
async def sync(
225217
self,
226-
ref_products: ReferenceProduct,
218+
ref_products: Dict[str, ReferenceProduct],
227219
ref_publishers: ReferencePublishers,
228220
ref_permissions: ReferencePermissions,
229-
ref_authority_permissions: Optional[ReferenceAuthorityPermissions],
221+
ref_authority_permissions: ReferenceAuthorityPermissions,
230222
send_transactions: bool = True,
231223
generate_keys: bool = False,
232224
allocate_price_v2: bool = True,
@@ -236,6 +228,20 @@ async def sync(
236228
# Fetch program accounts from the network
237229
await self.refresh_program_accounts()
238230

231+
# Sync authority permissions
232+
(
233+
authority_instructions,
234+
authority_signers,
235+
) = await self.sync_authority_permissions_instructions(
236+
ref_authority_permissions
237+
)
238+
239+
if authority_instructions:
240+
instructions.extend(authority_instructions)
241+
242+
if send_transactions:
243+
await self.send_transaction(authority_instructions, authority_signers)
244+
239245
# Sync mapping accounts
240246
mapping_instructions, mapping_keypairs = await self.sync_mapping_instructions(
241247
generate_keys
@@ -293,28 +299,6 @@ async def sync(
293299
if send_transactions:
294300
await self.send_transaction(price_instructions, price_keypairs)
295301

296-
if ref_authority_permissions:
297-
# Sync authority permissions
298-
(
299-
authority_instructions,
300-
authority_signers,
301-
) = await self.sync_authority_permissions_instructions(
302-
ref_authority_permissions
303-
)
304-
305-
if authority_instructions:
306-
instructions.extend(authority_instructions)
307-
308-
if send_transactions:
309-
await self.send_transaction(
310-
authority_instructions, authority_signers
311-
)
312-
313-
else:
314-
logger.debug(
315-
"Reference data for authority permissions is not defined, skipping..."
316-
)
317-
318302
return instructions
319303

320304
async def sync_mapping_instructions(

program_admin/cli.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def set_minimum_publishers(funding_key, program_key, price_key, value, outfile):
119119
@click.option("--funding-key", help="Funding key", envvar="FUNDING_KEY")
120120
@click.option("--program-key", help="Pyth program key", envvar="PROGRAM_KEY")
121121
@click.option("--product-key", help="Product account key", envvar="PRODUCT_KEY")
122-
@click.option("--metadata", help="Metadata to add to product", type=dict)
122+
@click.option("--metadata", help="Metadata to add to product", type=str)
123123
@click.option(
124124
"--outfile",
125125
help="File location to write instructions",
@@ -130,7 +130,9 @@ def update_product_metadata(funding_key, program_key, product_key, metadata, out
130130
funding = PublicKey(funding_key)
131131
program = PublicKey(program_key)
132132
product = PublicKey(product_key)
133-
instruction = instructions.update_product(program, funding, product, metadata)
133+
instruction = instructions.update_product(
134+
program, funding, product, json.loads(metadata)
135+
)
134136

135137
instruction_output = json.dumps(
136138
[
@@ -448,12 +450,10 @@ def sync(
448450
ref_permissions = parse_permissions_with_overrides(
449451
Path(permissions), Path(overrides), network
450452
)
451-
ref_authority_permissions = None
452453

453-
if authority_permissions:
454-
ref_authority_permissions = parse_authority_permissions_json(
455-
Path(authority_permissions)
456-
)
454+
ref_authority_permissions = parse_authority_permissions_json(
455+
Path(authority_permissions)
456+
)
457457

458458
asyncio.run(
459459
program_admin.sync(

program_admin/instructions.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from solana.transaction import AccountMeta, TransactionInstruction
77

88
from program_admin.types import ReferenceAuthorityPermissions
9-
from program_admin.util import encode_product_metadata
9+
from program_admin.util import encode_product_metadata, get_permissions_account
1010

1111
# TODO: Implement add_mapping instruction
1212

@@ -44,11 +44,16 @@ def init_mapping(
4444
layout = Struct("version" / Int32ul, "command" / Int32sl)
4545
data = layout.build(dict(version=PROGRAM_VERSION, command=COMMAND_INIT_MAPPING))
4646

47+
permissions_account = get_permissions_account(
48+
program_key, AUTHORITY_PERMISSIONS_PDA_SEED
49+
)
50+
4751
return TransactionInstruction(
4852
data=data,
4953
keys=[
5054
AccountMeta(pubkey=funding_key, is_signer=True, is_writable=True),
5155
AccountMeta(pubkey=mapping_key, is_signer=True, is_writable=True),
56+
AccountMeta(pubkey=permissions_account, is_signer=False, is_writable=True),
5257
],
5358
program_id=program_key,
5459
)
@@ -71,12 +76,17 @@ def add_product(
7176
layout = Struct("version" / Int32ul, "command" / Int32sl)
7277
data = layout.build(dict(version=PROGRAM_VERSION, command=COMMAND_ADD_PRODUCT))
7378

79+
permissions_account = get_permissions_account(
80+
program_key, AUTHORITY_PERMISSIONS_PDA_SEED
81+
)
82+
7483
return TransactionInstruction(
7584
data=data,
7685
keys=[
7786
AccountMeta(pubkey=funding_key, is_signer=True, is_writable=True),
7887
AccountMeta(pubkey=mapping_key, is_signer=True, is_writable=True),
7988
AccountMeta(pubkey=new_product_key, is_signer=True, is_writable=True),
89+
AccountMeta(pubkey=permissions_account, is_signer=False, is_writable=True),
8090
],
8191
program_id=program_key,
8292
)
@@ -124,11 +134,16 @@ def update_product(
124134
data = layout.build(dict(version=PROGRAM_VERSION, command=COMMAND_UPD_PRODUCT))
125135
data_extra = encode_product_metadata(product_metadata)
126136

137+
permissions_account = get_permissions_account(
138+
program_key, AUTHORITY_PERMISSIONS_PDA_SEED
139+
)
140+
127141
return TransactionInstruction(
128142
data=data + data_extra,
129143
keys=[
130144
AccountMeta(pubkey=funding_key, is_signer=True, is_writable=True),
131145
AccountMeta(pubkey=product_key, is_signer=True, is_writable=True),
146+
AccountMeta(pubkey=permissions_account, is_signer=False, is_writable=True),
132147
],
133148
program_id=program_key,
134149
)
@@ -162,12 +177,17 @@ def add_price(
162177
)
163178
)
164179

180+
permissions_account = get_permissions_account(
181+
program_key, AUTHORITY_PERMISSIONS_PDA_SEED
182+
)
183+
165184
return TransactionInstruction(
166185
data=data,
167186
keys=[
168187
AccountMeta(pubkey=funding_key, is_signer=True, is_writable=True),
169188
AccountMeta(pubkey=product_key, is_signer=True, is_writable=True),
170189
AccountMeta(pubkey=new_price_key, is_signer=True, is_writable=True),
190+
AccountMeta(pubkey=permissions_account, is_signer=False, is_writable=True),
171191
],
172192
program_id=program_key,
173193
)
@@ -222,11 +242,16 @@ def set_minimum_publishers(
222242
)
223243
)
224244

245+
permissions_account = get_permissions_account(
246+
program_key, AUTHORITY_PERMISSIONS_PDA_SEED
247+
)
248+
225249
return TransactionInstruction(
226250
data=data,
227251
keys=[
228252
AccountMeta(pubkey=funding_key, is_signer=True, is_writable=True),
229253
AccountMeta(pubkey=price_account_key, is_signer=True, is_writable=True),
254+
AccountMeta(pubkey=permissions_account, is_signer=False, is_writable=True),
230255
],
231256
program_id=program_key,
232257
)
@@ -257,11 +282,16 @@ def toggle_publisher(
257282
)
258283
)
259284

285+
permissions_account = get_permissions_account(
286+
program_key, AUTHORITY_PERMISSIONS_PDA_SEED
287+
)
288+
260289
return TransactionInstruction(
261290
data=data,
262291
keys=[
263292
AccountMeta(pubkey=funding_key, is_signer=True, is_writable=True),
264293
AccountMeta(pubkey=price_account_key, is_signer=True, is_writable=True),
294+
AccountMeta(pubkey=permissions_account, is_signer=False, is_writable=True),
265295
],
266296
program_id=program_key,
267297
)
@@ -306,9 +336,8 @@ def upd_permissions(
306336
)
307337
)
308338

309-
[permissions_account, _bump] = PublicKey.find_program_address(
310-
[AUTHORITY_PERMISSIONS_PDA_SEED],
311-
program_key,
339+
permissions_account = get_permissions_account(
340+
program_key, AUTHORITY_PERMISSIONS_PDA_SEED
312341
)
313342

314343
# Under the BPF upgradeable loader, the program data key is a PDA
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
from .accept import AcceptAccounts, accept
22
from .propose import ProposeAccounts, propose
33
from .revert import RevertAccounts, revert
4+
5+
assert AcceptAccounts
6+
assert accept
7+
assert ProposeAccounts
8+
assert propose
9+
assert RevertAccounts
10+
assert revert

0 commit comments

Comments
 (0)