ApeWorX / ape

The smart contract development tool for Pythonistas, Data Scientists, and Security Professionals
https://apeworx.io
Apache License 2.0
872 stars 133 forks source link

crash on long event query after refusing to connect to localhost #1917

Closed wakamex closed 7 months ago

wakamex commented 7 months ago

Environment information

$ ape --version
0.7.8.dev6+g52f431bf

$ ape plugins list
  alchemy      0.7.1.dev10+gf332896.d20240201
  arbitrum     0.7.2
  base         0.7.1
  etherscan    0.7.1.dev1+g89b7d26
  optimism     0.7.2
  polygon      0.7.1
  solidity     0.7.1
$ cat ape-config.yaml
cat: ape-config.yaml: No such file or directory

What went wrong?

Please include information like:

Here are different commands with their associated outputs

# %%
from ape import Contract, networks
from dotenv import load_dotenv

load_dotenv()

# %%
# this works on my local node
with networks.parse_network_choice('ethereum:local:http://localhost:8545') as provider:
    v2_abi = '[{"anonymous": false,"inputs": [{ "indexed": true, "name": "reportTimestamp", "type": "uint256" },{ "indexed": false, "name": "timeElapsed", "type": "uint256" },{ "indexed": false, "name": "preTotalShares", "type": "uint256" },{ "indexed": false, "name": "preTotalEther", "type": "uint256" },{ "indexed": false, "name": "postTotalShares", "type": "uint256" },{ "indexed": false, "name": "postTotalEther", "type": "uint256" },{ "indexed": false, "name": "sharesMintedAsFees", "type": "uint256" }],"name": "TokenRebased","type": "event"}]'
    steth = Contract("0xae7ab96520de3a18e5e111b5eaab095312d7fe84",abi=v2_abi)  # Lido v2 main contract
    events2 = steth.TokenRebased.query("*")
print(events2.head())
output="""
1  0xe9ba59b2b3e83d93df52528d5e17c802973f5de34602...                  3  
2  0xbf52777e4dd583d52104be96f7da420be977faeee97c...                 10  
3  0x5489a6364dc63a9b2614c7665d15827fa3b100c80dcb...                212  
4  0x54b86d0ca8df20f49ad14c3fa2899b9b21cbe144b1df...                  6  
"""

# %%
# ignores localhost, connects to public node, sometimes fails right away
with networks.parse_network_choice('ethereum:mainnet:http://localhost:8545') as provider:
    v2_abi = '[{"anonymous": false,"inputs": [{ "indexed": true, "name": "reportTimestamp", "type": "uint256" },{ "indexed": false, "name": "timeElapsed", "type": "uint256" },{ "indexed": false, "name": "preTotalShares", "type": "uint256" },{ "indexed": false, "name": "preTotalEther", "type": "uint256" },{ "indexed": false, "name": "postTotalShares", "type": "uint256" },{ "indexed": false, "name": "postTotalEther", "type": "uint256" },{ "indexed": false, "name": "sharesMintedAsFees", "type": "uint256" }],"name": "TokenRebased","type": "event"}]'
    steth = Contract("0xae7ab96520de3a18e5e111b5eaab095312d7fe84",abi=v2_abi)  # Lido v2 main contract
    events2 = steth.TokenRebased.query("*")
print(events2.head())
output="""
ProviderError: No (supported) node found on 'https://mainnet.infura.io/[hidden]'.
"""

# %%
# same thing, sometimes fails later
with networks.parse_network_choice('ethereum:mainnet:http://localhost:8545') as provider:
    v2_abi = '[{"anonymous": false,"inputs": [{ "indexed": true, "name": "reportTimestamp", "type": "uint256" },{ "indexed": false, "name": "timeElapsed", "type": "uint256" },{ "indexed": false, "name": "preTotalShares", "type": "uint256" },{ "indexed": false, "name": "preTotalEther", "type": "uint256" },{ "indexed": false, "name": "postTotalShares", "type": "uint256" },{ "indexed": false, "name": "postTotalEther", "type": "uint256" },{ "indexed": false, "name": "sharesMintedAsFees", "type": "uint256" }],"name": "TokenRebased","type": "event"}]'
    steth = Contract("0xae7ab96520de3a18e5e111b5eaab095312d7fe84",abi=v2_abi)  # Lido v2 main contract
    events2 = steth.TokenRebased.query("*")
print(events2.head())
output="""
INFO: Connecting to a 'mevblocker' node.
INFO: `ape-cache` database has not been initialized
CannotHandleRequest: Could not discover provider while making request: method:eth_getLogs
params:[{'address': ['0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84'], 'fromBlock': '0x9c40', 'toBlock': '0xafc7', 'topics': ['0xff08c3ef606d198e316ef5b822193c489965899eb4e3c248cea1a4626c3eda50']}]
"""

# %%
# also ignores localhost in this setup, with Contract creation done on a public node
with networks.parse_network_choice('ethereum:mainnet:https://ethereum.publicnode.com') as provider:
    steth = Contract("0xae7ab96520de3a18e5e111b5eaab095312d7fe84")  # Lido v2 main contract
with networks.parse_network_choice('ethereum:mainnet:http://localhost:8545') as provider:
    events2 = steth.TokenRebased.query("*")
print(events2.head())
output="""
ProviderError: No (supported) node found on 'https://api.mycryptoapi.com/[hidden]'.
"""

# %%
# fails to connect to localhost on https
with networks.parse_network_choice('ethereum:mainnet:https://ethereum.publicnode.com') as provider:
    steth = Contract("0xae7ab96520de3a18e5e111b5eaab095312d7fe84")  # Lido v2 main contract
with networks.parse_network_choice('ethereum:mainnet:https://localhost:8545') as provider:
    events2 = steth.TokenRebased.query("*")
print(events2.head())
output="""
ProviderError: No (supported) node found on 'https://localhost:8545/[hidden]'.
"""

# %%
# let's try with alchemy
with networks.parse_network_choice('ethereum:mainnet:alchemy') as provider:
    v2_abi = '[{"anonymous": false,"inputs": [{ "indexed": true, "name": "reportTimestamp", "type": "uint256" },{ "indexed": false, "name": "timeElapsed", "type": "uint256" },{ "indexed": false, "name": "preTotalShares", "type": "uint256" },{ "indexed": false, "name": "preTotalEther", "type": "uint256" },{ "indexed": false, "name": "postTotalShares", "type": "uint256" },{ "indexed": false, "name": "postTotalEther", "type": "uint256" },{ "indexed": false, "name": "sharesMintedAsFees", "type": "uint256" }],"name": "TokenRebased","type": "event"}]'
    steth = Contract("0xae7ab96520de3a18e5e111b5eaab095312d7fe84",abi=v2_abi)  # Lido v2 main contract
    events2 = steth.TokenRebased.query("*")
print(events2.head())
output="""
INFO (ape-alchemy): Alchemy compute units exceeded, retrying, attempt 1/3 in 1000 ms
INFO (ape-alchemy): Alchemy compute units exceeded, retrying, attempt 1/3 in 1000 ms
INFO (ape-alchemy): Alchemy compute units exceeded, retrying, attempt 1/3 in 1000 ms
INFO (ape-alchemy): Alchemy compute units exceeded, retrying, attempt 1/3 in 1000 ms
                                          block_hash  block_number  \
0  0x9b6092ee244f7e5aeca8aae2d5b37f27fd6dec42a6b5...      17272708   
1  0x806076ed876d8b561743d9467631f9edf98cf7e11cdd...      17279454   
2  0xba9ae76baef8ef7c1cbb5717836d44647aff838e7875...      17286461   
3  0x4e044d2e267f5f4037d04c13f40752895c8e02555a07...      17293521   
4  0x76bd4ec2fe5d0ccc8ed42e4f4eba00734750e0b74547...      17300635   

                             contract_address  \
0  0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84   
1  0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84   
2  0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84   
3  0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84   
4  0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84   

How can it be fixed?

Network parsing should let me use ethereum:mainnet:http://localhost so that I can use the default etherscan explorer to pull up contracts. or let me programmatically specify an explorer when connecting to a local node. The long event query shouldn't crash, possibly due to rate limiting? The fact that this works with my bitchin rate limit retry PR for ape-alchemy makes me think we should have retry logic for all networks.

linear[bot] commented 7 months ago

APE-1670 crash on long event query after refusing to connect to localhost

antazoey commented 7 months ago

ah, this was a regression from the default public node work (i can see the bug). Pr soon.

antazoey commented 7 months ago

as a temporary work-around I think if you switch the port it will work, but i do have a fix incoming