Skip to content

Commit

Permalink
update batching
Browse files Browse the repository at this point in the history
  • Loading branch information
Tburm committed Sep 25, 2024
1 parent f7022be commit 2169de2
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 18 deletions.
11 changes: 5 additions & 6 deletions src/synthetix/perps/perps.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
call_erc7412,
multicall_erc7412,
write_erc7412,
make_fulfillment_request,
make_pyth_fulfillment_request,
)
from .constants import DISABLED_MARKETS
from .perps_utils import unpack_bfp_configuration, unpack_bfp_configuration_by_id
Expand Down Expand Up @@ -230,15 +230,14 @@ def _prepare_oracle_call(self, market_names: [str] = []):
price_metadata = pyth_data["meta"]

# prepare the oracle call
raw_feed_ids = [decode_hex(feed_id) for feed_id in feed_ids]
args = (1, 30, raw_feed_ids)

to, data, _ = make_fulfillment_request(
to, data, _ = make_pyth_fulfillment_request(
self.snx,
self.snx.contracts["pyth_erc7412_wrapper"]["PythERC7412Wrapper"]["address"],
1, # update type
feed_ids,
price_update_data,
30, # staleness tolerance
0,
args,
)
value = len(market_names)

Expand Down
53 changes: 41 additions & 12 deletions src/synthetix/utils/multicall.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,38 +80,51 @@ def decode_erc7412_oracle_data_required_error(snx, error):
raise Exception("Error data can not be decoded")


def make_pyth_fulfillment_request(snx, address, update_type, feed_ids, price_update_data, publish_time_or_staleness, fee):
def make_pyth_fulfillment_request(
snx,
address,
update_type,
feed_ids,
price_update_data,
publish_time_or_staleness,
fee,
):
# log all of the inputs
erc_contract = snx.web3.eth.contract(
address=address,
abi=snx.contracts["pyth_erc7412_wrapper"]["PythERC7412Wrapper"]["abi"],
)

#update_type, publish_time_or_staleness, feed_ids = args
# update_type, publish_time_or_staleness, feed_ids = args
feed_ids = [decode_hex(f) for f in feed_ids]
encoded_args = encode(
["uint8", "uint64", "bytes32[]", "bytes[]"],
[update_type, publish_time_or_staleness, feed_ids, price_update_data],
)

# assume 1 wei per price update
value = fee if fee > 0 else len(price_update_data) * 1
value = fee if fee > 0 else len(feed_ids) * 1

update_tx = erc_contract.functions.fulfillOracleQuery(
encoded_args
).build_transaction({"value": value, "gas": None})
return update_tx["to"], update_tx["data"], update_tx["value"]


class PythVaaRequest:
feed_ids: list[HexStr] = []
publish_time = 0
fee = 0


class ERC7412Requests:
pyth_address = ''
pyth_address = ""
pyth_latest: list[HexStr] = []
pyth_latest_fee = 0
pyth_vaa: list[PythVaaRequest] = []

def aggregate_erc7412_price_requests(snx, error, requests = None)

def aggregate_erc7412_price_requests(snx, error, requests=None):
"Figures out all the prices that have been requested by an ERC7412 error and puts them all in aggregated requests"
if not requests:
requests = ERC7412Requests()
Expand All @@ -120,15 +133,17 @@ def aggregate_erc7412_price_requests(snx, error, requests = None)

# TODO: execute in parallel
for sub_error in errors:
aggregate_erc7412_price_requests(snx, sub_error, requests)
requests = aggregate_erc7412_price_requests(snx, sub_error, requests)

return requests

if type(error) is ContractCustomError and (
error.data.startswith(SELECTOR_ORACLE_DATA_REQUIRED)
or error.data.startswith(SELECTOR_ORACLE_DATA_REQUIRED_WITH_FEE)
):
# decode error data
update_type = None
address = ''
address = ""
feed_ids = []
fee = 0
args = []
Expand Down Expand Up @@ -175,10 +190,10 @@ def aggregate_erc7412_price_requests(snx, error, requests = None)

return requests


def handle_erc7412_error(snx, error):
"When receiving a ERC7412 error, will return an updated list of calls with the required price updates"
requests = aggregate_erc7412_price_requests(snx, error)

calls = []

if requests.pyth_latest:
Expand All @@ -201,20 +216,34 @@ def handle_erc7412_error(snx, error):
# create a new request
# TODO: the actual number should go here for staleness
to, data, value = make_pyth_fulfillment_request(
snx, requests.pyth_address, 1, requests.pyth_latest, price_update_data, 3600, requests.pyth_latest_fee
snx,
requests.pyth_address,
1,
requests.pyth_latest,
price_update_data,
3600,
requests.pyth_latest_fee,
)

calls.append((to, True, value, data))

if requests.pyth_vaa:
for r in requests.pyth_vaa:
# fetch the data from pyth for those feed ids
pyth_data = snx.pyth.get_price_from_ids(r.feed_ids, publish_time=r.publish_time)
pyth_data = snx.pyth.get_price_from_ids(
r.feed_ids, publish_time=r.publish_time
)
price_update_data = pyth_data["price_update_data"]

# create a new request
to, data, value = make_pyth_fulfillment_request(
snx, requests.pyth_address, 2, r.feed_ids, price_update_data, r.publish_time, r.fee
snx,
requests.pyth_address,
2,
r.feed_ids,
price_update_data,
r.publish_time,
r.fee,
)

calls.append((to, True, value, data))
Expand Down Expand Up @@ -346,4 +375,4 @@ def multicall_erc7412(
snx.logger.debug(f"Simulation failed, decoding the error {e}")

# handle the error by appending calls
calls = handle_erc7412_error(snx, e, calls)
calls = handle_erc7412_error(snx, e) + calls

0 comments on commit 2169de2

Please sign in to comment.