Best Practices
Success Rate Definition
We present users with a more stringent success rate measurement. Any request that does not receive the expected response is considered unsuccessful in our statistics. This includes, but is not limited to:
Any request that triggers BlockPI RPC restrictions, including rate limits, block range limitations, data size limitations, etc.
Any error directly returned from the node, such as non-existent methods, incorrect parameters, missing parameters, etc.
Others, such as timeout error.
Using Archive Mode
BlockPI Network RPC service allow users to set their endpoint to be with different features, such as Archive mode.
When the archive mode is on for a specific endpoint, the requests sent to this endpoint will be routed to archive nodes. And it typically takes a longer time to process due to the huge amount of data.
In this case, you would need to generate two endpoints:
one for handling regular requests.
another with Archive mode enabled exclusively for processing requests that require archive data. And send requests based on conditions.
Here is an example:
# Send requests for data that predates 128 blocks to the archive nodes
def request():
# generate two keys, one is with archive mode enabled
fullNodeUrl = "https://ethereum.blockpi.network/v1/rpc/<key-normal>"
archiveNodeUrl = "https://ethereum.blockpi.network/v1/rpc/<key-with-archive-mode-on>"
#target block number
blockNum = "0x10336aa"
# get the latest block number
payload = {"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 83}
headers = {"Content-Type": "application/json"}
latestNum = requests.post(fullNodeUrl,headers=headers, data=json.dumps(payload)).json()['result']
# Send the request to the desired endpoint.
traceBlockPayload = {"jsonrpc":"2.0","method":"trace_block","params":[blockNum],"id":1}
if int(latestNum,16) - int(blockNum,16) >= 128 :
resp = requests.post(archiveNodeUrl,headers=headers, data=json.dumps(traceBlockPayload))
print(resp.text)
else:
resp = requests.post(fullNodeUrl,headers=headers, data=json.dumps(traceBlockPayload))
print(resp.text)
Segment Block Range in eth_getLogs
Here is another one with using the eth_getLogs. As the method consumes decent sever resource.
Our limit on eth_getLogs block range are as follows: if no parameters are included, a single eth_getLogs request is limited to 1024 blocks. If the request includes either the topic parameter or the address parameter, the limit is set to 5000.
If users need to query a block range more than this limit, you can segment it to multiple requests with certain blocks each.
import json
import requests
fullNodeUrl = "https://ethereum.blockpi.network/v1/rpc/<your-api-key>"
headers = {"Content-Type": "application/json"}
interval = 1000
def get_logs(from_block_number, to_block_number):
logs = []
while from_block_number <= to_block_number:
end_block_number = min(to_block_number, from_block_number + interval)
payload = {
"jsonrpc": "2.0",
"id": 1,
"method": "eth_getLogs",
"params": [{
"fromBlock": hex(from_block_number),
"toBlock": hex(end_block_number)
}]
}
response = requests.post(fullNodeUrl, headers=headers, data=json.dumps(payload))
if response.status_code != 200:
raise Exception("Failed to retrieve logs for block range:", from_block_number, end_block_number)
result = response.json()["result"]
logs.extend(result)
from_block_number = end_block_number + 1
print(response.json())
return logs
def get_all_logs(from_block_number, to_block_number):
logs = []
current_block_number = from_block_number
while current_block_number <= to_block_number:
end_block_number = current_block_number + interval
logs_in_range = get_logs(current_block_number, end_block_number)
logs.extend(logs_in_range)
print("Processed block range:", current_block_number, "-", end_block_number, ", total logs:", len(logs_in_range))
current_block_number = end_block_number + 1
return logs
from_block_number = 10962850
to_block_number = 10962950
logs = get_all_logs(from_block_number, to_block_number)
print("Total logs:", len(logs))
Websocket Reconnection
To safeguard the system, each RPC provider sets a periodic disconnection (timeout) for WebSocket connections. In the case of BlockPI, the timeout is set to 30 minutes. Therefore, during development, users need to implement a mechanism to detect and handle reconnection when the connection is dropped. Here is a Python example:
import asyncio
import json
import websockets
async def connect(url):
while True:
try:
async with websockets.connect(url) as ws:
print("websocket connection is established")
request = {
"jsonrpc": "2.0",
"id": 2,
"method": "eth_subscribe",
"params": ["newHeads"]
}
await ws.send(json.dumps(request))
while True:
message = await ws.recv()
print("message received:", message)
except websockets.exceptions.ConnectionClosedError as e:
if str(e) == 'no close frame received or sent':
print("keepalive triggered,reconnecting...")
await asyncio.sleep(5)
continue
else:
print("websocket alive")
return
except Exception as e:
print("Unknown error occurred:", e)
await asyncio.sleep(5)
continue
if __name__ == "__main__":
url = "wss://polygon-mumbai.blockpi.network/v1/ws/d69ca19cf64365849ca8152b7f32f319bad9fc22"
asyncio.run(connect(url))
Please note that this is just a sample code, and you may need to adapt it to your specific development environment and requirements.
Restrictions for Different Endpoint Types
In order to better serve different types of users and ensure the healthy and efficient operation of BlockPI RPC service network, we have implemented different restrictions on various types of endpoints. If a user triggers any of these restrictions, the system will return an error. The following table outlines these limitations:
Public
Not support WS/WSS
N/A
Public
Not support Debug_* and Trace_*
-32000
Public
Maximum request rate: 10 qps
429
Public
Maximum response body size: 3 MB
-32000
Public
Maximum block range: 1024
-32602
Public
Maximum batch size: 10
-32000
Private
Maximum block range: 5000 with address input
-32602
Private
Only support “callTracer” and ”prestateTracer” for debug method
-32000
Private HTTPS
Maximum batch size: 1000
-32000
Private WSS
Do not support batch call
-32000
All HTTPS
Do not support subscribe and filter rpc method
-32000
Last updated
Was this helpful?