From 7037f9188851e24c61e9e7d6148bd60676520b0c Mon Sep 17 00:00:00 2001 From: trizin <25263018+trizin@users.noreply.github.com> Date: Wed, 16 Aug 2023 13:42:04 +0300 Subject: [PATCH 1/5] Infinite approval and cache allowance --- pdr_backend/utils/contract.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pdr_backend/utils/contract.py b/pdr_backend/utils/contract.py index 4aef54e07..632837731 100644 --- a/pdr_backend/utils/contract.py +++ b/pdr_backend/utils/contract.py @@ -14,6 +14,7 @@ from eth_keys.backends import NativeECCBackend from sapphirepy import wrapper from pathlib import Path +from web3.constants import MAX_INT from web3 import Web3, HTTPProvider, WebsocketProvider from web3.middleware import construct_sign_and_send_raw_middleware from web3.logs import DISCARD @@ -127,6 +128,7 @@ def __init__(self, config: Web3Config, address: str): ) stake_token = self.get_stake_token() self.token = Token(config, stake_token) + self.last_allowance = 0 def is_valid_subscription(self): return self.contract_instance.functions.isValidSubscription( @@ -364,17 +366,17 @@ def submit_prediction( amount_wei = self.config.w3.to_wei(str(stake_amount), "ether") # Check allowance first, only approve if needed - current_allowance = self.token.allowance( - self.config.owner, self.contract_address - ) - if current_allowance < amount_wei: + if self.last_allowance == 0: + self.last_allowance = self.token.allowance( + self.config.owner, self.contract_address + ) + if self.last_allowance < amount_wei: try: - self.token.approve(self.contract_address, amount_wei) + self.token.approve(self.contract_address, MAX_INT) except Exception as e: print("Error while approving the contract to spend tokens:", e) return None - self.token.approve(self.contract_address, amount_wei) gasPrice = self.config.w3.eth.gas_price try: txhash = None @@ -405,7 +407,7 @@ def submit_prediction( predicted_value, amount_wei, prediction_ts ).transact({"from": self.config.owner, "gasPrice": gasPrice}) txhash = tx.hex() - + self.last_allowance -= amount_wei print(f"Submitted prediction, txhash: {txhash}") if not wait_for_receipt: return txhash From 6c49ce1f8d1f157ff14985080cf8ae90cc4bec9f Mon Sep 17 00:00:00 2001 From: trizin <25263018+trizin@users.noreply.github.com> Date: Wed, 16 Aug 2023 14:02:49 +0300 Subject: [PATCH 2/5] Cache on approve --- pdr_backend/utils/contract.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pdr_backend/utils/contract.py b/pdr_backend/utils/contract.py index 632837731..aec1d98e9 100644 --- a/pdr_backend/utils/contract.py +++ b/pdr_backend/utils/contract.py @@ -373,6 +373,9 @@ def submit_prediction( if self.last_allowance < amount_wei: try: self.token.approve(self.contract_address, MAX_INT) + self.last_allowance = self.token.allowance( + self.config.owner, self.contract_address + ) except Exception as e: print("Error while approving the contract to spend tokens:", e) return None From bb39e6bda9b02794d2ba55bbe979004a5cc0f3db Mon Sep 17 00:00:00 2001 From: trizin <25263018+trizin@users.noreply.github.com> Date: Wed, 16 Aug 2023 14:02:58 +0300 Subject: [PATCH 3/5] Cache contract objects --- pdr_backend/predictoor/main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pdr_backend/predictoor/main.py b/pdr_backend/predictoor/main.py index 18305a028..189892432 100644 --- a/pdr_backend/predictoor/main.py +++ b/pdr_backend/predictoor/main.py @@ -15,6 +15,7 @@ last_block_time = 0 topics: Dict[str, dict] = {} +contract_map: Dict[str, PredictoorContract] = {} rpc_url = env.get_rpc_url_or_exit() subgraph_url = env.get_subgraph_or_exit() @@ -42,7 +43,9 @@ def process_block(block): print(f"Got new block: {block['number']} with {len(topics)} topics") for address in topics: topic = topics[address] - predictoor_contract = PredictoorContract(web3_config, address) + if contract_map.get(address) is None: + contract_map[address] = PredictoorContract(web3_config, address) + predictoor_contract = contract_map[address] epoch = predictoor_contract.get_current_epoch() seconds_per_epoch = predictoor_contract.get_secondsPerEpoch() seconds_till_epoch_end = ( From d766b90ffcef51cdcb5c27d23123abc227457319 Mon Sep 17 00:00:00 2001 From: trizin <25263018+trizin@users.noreply.github.com> Date: Wed, 16 Aug 2023 14:18:13 +0300 Subject: [PATCH 4/5] Add MAX_UINT const --- pdr_backend/utils/constants.py | 2 ++ pdr_backend/utils/contract.py | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pdr_backend/utils/constants.py b/pdr_backend/utils/constants.py index fcf0068f7..4b0a717e0 100644 --- a/pdr_backend/utils/constants.py +++ b/pdr_backend/utils/constants.py @@ -1,4 +1,6 @@ ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" +MAX_UINT = 2**256 - 1 + SAPPHIRE_TESTNET_RPC = "https://testnet.sapphire.oasis.dev" SAPPHIRE_TESTNET_CHAINID = 23295 SAPPHIRE_MAINNET_RPC = "https://sapphire.oasis.io" diff --git a/pdr_backend/utils/contract.py b/pdr_backend/utils/contract.py index aec1d98e9..3039f0b7e 100644 --- a/pdr_backend/utils/contract.py +++ b/pdr_backend/utils/contract.py @@ -14,16 +14,15 @@ from eth_keys.backends import NativeECCBackend from sapphirepy import wrapper from pathlib import Path -from web3.constants import MAX_INT from web3 import Web3, HTTPProvider, WebsocketProvider from web3.middleware import construct_sign_and_send_raw_middleware from web3.logs import DISCARD - from pdr_backend.utils.constants import ( ZERO_ADDRESS, SAPPHIRE_TESTNET_CHAINID, SAPPHIRE_MAINNET_CHAINID, + MAX_UINT, ) keys = KeyAPI(NativeECCBackend) @@ -372,7 +371,7 @@ def submit_prediction( ) if self.last_allowance < amount_wei: try: - self.token.approve(self.contract_address, MAX_INT) + self.token.approve(self.contract_address, MAX_UINT) self.last_allowance = self.token.allowance( self.config.owner, self.contract_address ) From 46ffeed1cf7bcd2c5ac4075d53543e0ab2a23402 Mon Sep 17 00:00:00 2001 From: trizin <25263018+trizin@users.noreply.github.com> Date: Wed, 16 Aug 2023 14:29:12 +0300 Subject: [PATCH 5/5] Fix --- pdr_backend/utils/contract.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pdr_backend/utils/contract.py b/pdr_backend/utils/contract.py index 3039f0b7e..2f97be406 100644 --- a/pdr_backend/utils/contract.py +++ b/pdr_backend/utils/contract.py @@ -365,16 +365,14 @@ def submit_prediction( amount_wei = self.config.w3.to_wei(str(stake_amount), "ether") # Check allowance first, only approve if needed - if self.last_allowance == 0: + if self.last_allowance <= 0: self.last_allowance = self.token.allowance( self.config.owner, self.contract_address ) if self.last_allowance < amount_wei: try: self.token.approve(self.contract_address, MAX_UINT) - self.last_allowance = self.token.allowance( - self.config.owner, self.contract_address - ) + self.last_allowance = MAX_UINT except Exception as e: print("Error while approving the contract to spend tokens:", e) return None