Skip to content

Commit

Permalink
Add a new contract used for debugging (#437)
Browse files Browse the repository at this point in the history
  • Loading branch information
kongzii authored Sep 30, 2024
1 parent c7c84dd commit ffa1a20
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 2 deletions.
29 changes: 29 additions & 0 deletions prediction_market_agent_tooling/abis/debuggingcontract.abi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[
{
"constant": false,
"inputs": [],
"name": "inc",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "counter",
"outputs": [{ "name": "", "type": "uint256" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getNow",
"outputs": [{ "name": "", "type": "uint32" }],
"payable": false,
"stateMutability": "view",
"type": "function"
}
]
50 changes: 49 additions & 1 deletion prediction_market_agent_tooling/tools/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import time
import typing as t
from contextlib import contextmanager
from datetime import datetime

import pytz
from pydantic import BaseModel, field_validator
from web3 import Web3

Expand All @@ -21,7 +23,11 @@
GNOSIS_NETWORK_ID,
GNOSIS_RPC_URL,
)
from prediction_market_agent_tooling.tools.utils import should_not_happen
from prediction_market_agent_tooling.tools.utils import (
DatetimeWithTimezone,
add_utc_timezone_validator,
should_not_happen,
)
from prediction_market_agent_tooling.tools.web3_utils import (
call_function_on_contract,
send_function_on_contract_tx,
Expand Down Expand Up @@ -423,6 +429,48 @@ def get_asset_token_contract(
return to_gnosis_chain_contract(super().get_asset_token_contract(web3=web3))


class DebuggingContract(ContractOnGnosisChain):
# Contract ABI taken from https://gnosisscan.io/address/0x5Aa82E068aE6a6a1C26c42E5a59520a74Cdb8998#code.
abi: ABI = abi_field_validator(
os.path.join(
os.path.dirname(os.path.realpath(__file__)),
"../abis/debuggingcontract.abi.json",
)
)
address: ChecksumAddress = Web3.to_checksum_address(
"0x5Aa82E068aE6a6a1C26c42E5a59520a74Cdb8998"
)

def getNow(
self,
web3: Web3 | None = None,
) -> int:
now: int = self.call(
function_name="getNow",
web3=web3,
)
return now

def get_now(
self,
web3: Web3 | None = None,
) -> DatetimeWithTimezone:
return add_utc_timezone_validator(
datetime.fromtimestamp(self.getNow(web3), tz=pytz.UTC)
)

def inc(
self,
api_keys: APIKeys,
web3: Web3 | None = None,
) -> TxReceipt:
return self.send(
api_keys=api_keys,
function_name="inc",
web3=web3,
)


def contract_implements_function(
contract_address: ChecksumAddress,
function_name: str,
Expand Down
13 changes: 13 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
import os

from web3 import Web3

from prediction_market_agent_tooling.config import APIKeys
from prediction_market_agent_tooling.tools.contract import DebuggingContract

RUN_PAID_TESTS = os.environ.get("RUN_PAID_TESTS", "0") == "1"


def mint_new_block(keys: APIKeys, web3: Web3) -> None:
"""
Mints a new block on the web3's blockchain.
Useful for tests that debends on chain's timestamp, this will update it.
"""
DebuggingContract().inc(keys, web3)
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import time

from ape_test import TestAccount
from eth_account import Account
from numpy import isclose
Expand All @@ -10,11 +12,14 @@
is_minimum_required_balance,
)
from prediction_market_agent_tooling.tools.balances import get_balances
from prediction_market_agent_tooling.tools.contract import DebuggingContract
from prediction_market_agent_tooling.tools.utils import utcnow
from prediction_market_agent_tooling.tools.web3_utils import (
send_xdai_to,
wei_to_xdai,
xdai_to_wei,
)
from tests.utils import mint_new_block


def test_connect_local_chain(local_web3: Web3) -> None:
Expand Down Expand Up @@ -93,3 +98,37 @@ def test_fresh_account_has_less_than_minimum_required_balance(
fresh_account_adr = Account.create().address
account_adr = Web3.to_checksum_address(fresh_account_adr)
assert not is_minimum_required_balance(account_adr, xdai_type(0.5), local_web3)


def test_now(local_web3: Web3, test_keys: APIKeys) -> None:
# we need to mint a new block to update timestamp
mint_new_block(test_keys, local_web3)
allowed_difference = 15 # seconds
chain_timestamp = DebuggingContract().getNow(local_web3)
utc_timestamp = int(utcnow().timestamp())
assert (
abs(chain_timestamp - utc_timestamp) <= allowed_difference
), f"chain_timestamp and utc_timestamp differ by more than {allowed_difference} seconds: {chain_timestamp=} {utc_timestamp=}"


def test_now_failed(local_web3: Web3, test_keys: APIKeys) -> None:
# Sleep a little to let the local chain go out of sync without updating the block
time.sleep(5)
allowed_difference = 5 # seconds
chain_timestamp = DebuggingContract().getNow(local_web3)
utc_timestamp = int(utcnow().timestamp())
assert (
abs(chain_timestamp - utc_timestamp) >= allowed_difference
), f"without minting a new block, timestamps should differ by more than {allowed_difference} seconds: {chain_timestamp=} {utc_timestamp=}"


def test_now_datetime(local_web3: Web3, test_keys: APIKeys) -> None:
# we need to mint a new block to update timestamp
mint_new_block(test_keys, local_web3)
allowed_difference = 15 # seconds
chain_datetime = DebuggingContract().get_now(local_web3)
utc_datetime = utcnow()
actual_difference = (utc_datetime - chain_datetime).total_seconds()
assert (
actual_difference <= allowed_difference
), f"chain_datetime and utc_datetime differ by more than {allowed_difference} seconds: {chain_datetime=} {utc_datetime=} {actual_difference=}"
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def test_place_bet_with_autodeposit(

# Check that we have xdai funds, but no wxdai funds
initial_balances = get_balances(address=test_keys.bet_from_address, web3=local_web3)
assert initial_balances.wxdai == xdai_type(0)
assert np.isclose(initial_balances.wxdai, xdai_type(0))
assert initial_balances.xdai > xdai_type(0)

# Try to place a bet with 90% of the xDai funds
Expand Down

0 comments on commit ffa1a20

Please sign in to comment.