bloXroute Labs
Published in

bloXroute Labs

Guide: Measuring Your Speed Improvement With The BDN

By bloXroute Labs Co-Founder & COO Eyal Markovich

We previously discussed the speed improvements that can be expected from the BDN and how this can translate to real money. Here, we will outline how you can measure the speed improvements yourself and the tools available to do so. We will be focusing on three areas of speed: sending transactions fast, hearing about new blocks fast, and hearing about new transactions fast.

Installing the Tools

We offer a set of tools that you can use to measure the speed improvements provided by the use of the BDN.

  • Measuring Tx Speed
  • Block Streaming feed
  • Transaction Streaming feed

These tools are open-sourced in the https://github.com/bloXroute-Labs/bxgateway/tree/master/src/bloxroute_cli repo and can be modified as needed.

To install the tools, use pip to install bloxroute-cli:

You will need to register a bloXroute account by visiting our Portal and following these instructions. You will receive a two week free trial to complete the tests. It is necessary that you save the artifacts provided during registration.

Finally, prepare the authorization header using the account-id and secret hash from the account registration. Please use the following Python code example as a reference.

import base64base64.b64encode(f”{account_id}:{secret_hash}”.encode(“utf-8”)).decode(“utf-8”)

Save the certificate as you will need to use it for the streaming feeds test.

Measuring the Transaction Speed

As discussed before, bloXroute can provide an expected 400–600ms performance improvement from sending transactions to the bloXroute Cloud-API vs other node as a service infrastructure providers (like Alchemy and Infura, for example). If you want to check for yourself that your transactions are propagated faster using the BDN, you can use the ready-to-use compare_tx_speed.py script.

Script: compare_tx_speed.py

The script allows you to send groups of transactions to Infura, Alchemy, and the Cloud-API to measure which transactions were faster (e.g. which were first to be included in a block by miners).

The script accepts several parameters: api keys for Infura and Alchemy (you can test with both or just one) and the bloXroute authorization header (as discussed above). In addition, it accepts parameters to construct the transactions, such as the sender key, receiver address, gas price, and how many groups of transactions to generate. You should check the current Ethereum gas price and use a fee that is estimated to be accepted by miners within 5 minutes (or you will need to check the results manually via etherscan).

The idea behind this script is very simple: a group of transactions is sent to the different providers with the same nonce and fees. The only thing that is different between the Infura/Alchemy and bloXroute (BLXR) transactions is some input data. Since the nonce and fees are the same, miners will accept the first transaction to their transaction pool and will ignore the other two transactions. By checking which transactions made it to the block, you know which transaction was faster to reach the miner who mined the block. The script waits for at least 30 seconds between each group to allow for more blocks and more miners.

Example

Here is an example of running the script using Infura, Alchemy, and bloXroute and using 10 groups of transactions.

$ python compare_tx_speed.py --infura-api-key XXXXXXXX --alchemy-api-key XXXXXXXX --blxr-auth-header XXXXXXXX --sender-private-key XXXXXXXX --receiver-address XXXXXXXX --gas-price 26 --num-tx-groups 10Initial check completed. Sleeping 30 sec.Sending tx group 1.2020–10–21 21:23:26.331092 — Sending transaction to https://eth-mainnet.alchemyapi.io/v2/XXXXXXXX. TX Hash: 0x13fff6fb807ebf475c9a9fa3e9a3ec2ea3cdc56e9a08fae9d2a3c0059b469bf02020–10–21 21:23:26.331818 — Sending transaction to https://mainnet.infura.io/v3/XXXXXXXX. TX Hash: 0xb108567bf6b4363d8b9204ee6feb01e441cea760041e83482f38a790d1a8b8f62020–10–21 21:23:26.332525 — Sending transaction to bloXroute Cloud-API. TX Hash: 0x2b0dfab424d7827a5bb6730b52f247740debe1c5f1a94cccf1ad9ab48508d0582020–10–21 21:23:26.556232 — Failed to use endpoint https://mainnet.infura.io/v3/XXXXXXXX to send raw tx 0xf86682010685060db884008255f0942e059e37367ba9f66a0f75ad17f3a9eb7ed8d063802225a0fb1663493a85541937b3ef20e68ec922d8abfe43c8bab605d4601f03f7965c46a066fa9e533e42795b01fd6b0132e48a92ea1a74a9d4f2c9f2bc3374ff54598e44, with result {‘jsonrpc’: ‘2.0’, ‘id’: 1, ‘error’: {‘code’: -32000, ‘message’: ‘replacement transaction underpriced’}} returned.2020–10–21 21:23:26.826088 — Failed to use endpoint https://eth-mainnet.alchemyapi.io/v2/XXXXXXXX to send raw tx 0xf86682010685060db884008255f0942e059e37367ba9f66a0f75ad17f3a9eb7ed8d063801126a0d0a3725fb721619b83f287201069fa046859f44159336e80dd90901a32ef717ea0141cad6b213383d49ca2cef7008b70034b8f86da8fccb8a2b134909b37141524, with result {‘jsonrpc’: ‘2.0’, ‘id’: 1, ‘error’: {‘code’: -32000, ‘message’: ‘replacement transaction underpriced’}} returned.Sleeping 30 sec.Sending tx group 2.2020–10–21 21:23:56.857102 — Sending transaction to https://eth-mainnet.alchemyapi.io/v2/XXXXXXXX. TX Hash: 0x1d8029ab7ba6a38b568f24ccb8cd9cedb6c238ca061856910f62215c652168d02020–10–21 21:23:56.857826 — Sending transaction to https://mainnet.infura.io/v3/XXXXXXXX. TX Hash: 0xa0099dfbccdef3bf1313b94b3b312069e28502088fed9eaf3ee38ddd0fb2274b2020–10–21 21:23:56.858504 — Sending transaction to bloXroute Cloud-API. TX Hash: 0xab6f2fefd3b9c2bce5ef0a0651bb33156a15a5570941e5622a9ea9775c31a25d2020–10–21 21:23:57.079767 — Failed to use endpoint https://mainnet.infura.io/v3/XXXXXXXX to send raw tx 0xf86682010785060db884008255f0942e059e37367ba9f66a0f75ad17f3a9eb7ed8d063802226a0a9a6db55648576066d113a222a06e4be0121cdb5e4127a5f5632b73f28264a79a00ca3e96030186f3406e35282e0b162af6b71e4746ec45678b0881ee7934ed06d, with result {‘jsonrpc’: ‘2.0’, ‘id’: 1, ‘error’: {‘code’: -32000, ‘message’: ‘replacement transaction underpriced’}} returned.Sleeping 30 sec.<Ignoring logs for next 8 groups>Sleeping 1 min before checking transaction status. — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -Summary:Sent 10 groups of transactions to bloXroute Cloud-API and other providers, 10 of them have been confirmed:Number of Alchemy transactions mined: 0Number of Infura transactions mined: 0Number of bloXrotue transactions mined: 10

Understanding the Results

For each group, you can see the three transactions that were sent. In the Summary section, you can see how many transactions were mined and sent to each provider. In the example above, all 10 transactions sent to bloXroute were mined, which indicates that all miners that created blocks included these transactions heard about the transactions sent to bloXroute first.

Block Streaming Feed

Your trading strategy is probably heavily dependent on hearing the latest state of the network. Many people need to check the state as soon as a new block is created (such as checking a smart contract’s balance, checking prices, etc.). In this section, we discuss a tool you can use to subscribe to new block feeds from bloXroute and Infura or Alchemy and compare the speed of each feed. The script is called compare_block_feeds.py

Script: compare_block_feeds.py

The script will open web socket connections to bloXroute’s Cloud-API and one of the node as service providers and will subscribe to the new head/block feed. It will compare the time each feed is providing the new block. A full readme is provided with the script.

The script is expecting a parameter — ssl-dir that points to the certificate you obtained when registering your account.

Example

Below is an example of running the script for 10 minutes, comparing Alchemy and bloXroute’s Cloud-API:

python compare_block_feeds.py --use-cloud-api --ssl-dir /home/…/external_gateway/registration_only --eth wss://eth-mainnet.ws.alchemyapi.io/v2/XXXXXXXX --num-intervals 1Initiating connection to: wss://eth.feed.blxrbdn.com:28333Initiating connection to: wss://eth-mainnet.ws.alchemyapi.io/v2/XXXXXXXXwebsockets endpoint: wss://eth.feed.blxrbdn.com:28333 establishedwebsockets endpoint: wss://eth-mainnet.ws.alchemyapi.io/v2/XXXXXXXX established — — — — — — — — — — — — — — — — — — — — — — — — — — -Interval: 600 seconds. End time: 2020–10–21 14:21:17Blocks summary:Number of new blocks received first from gateway: 37Number of new blocks received first from node: 0Total number of blocks seen: 37Total blocks from gateway: 46Total blocks from eth node: 45Analysis of Blocks received on both feeds:Number of blocks: 36Number of blocks received from Gateway first: 36Number of blocks received from Ethereum node first: 0Percentage of blocks seen first from gateway: 100%Average time difference for blocks received first from gateway (ms): 3669.7Average time difference for blocks received first from Ethereum node (ms): 01 of 1 intervals complete. Exiting.

Understanding the Results

You should verify that the same amount of blocks were received on both feeds (the bloXroute feed might provide a slightly higher number of blocks because of how we handle forks). You should check the percentage of blocks received first from the BDN and the average time difference for blocks received first from the BDN/node provider. In the example above, 100% of the blocks were received first from the BDN with an average difference of 3.6 sec.

Transactions Streaming Feed

Similar to block streaming, streaming transactions is important for anyone that needs to make decisions based on pending transactions (this is critical for traders but can affect others as well).

In this section, we discuss a tool you can use to subscribe to new pending transactions feeds from Infura or Alchemy and from bloXroute, comparing the speed of each. The script is called compare_tx_feeds.py

Script: compare_tx_feeds.py

The script will open web socket connections to bloXroute’s Cloud-API and one of the node as service providers and will subscribe to the newPendingTransactions feed and to newTxs feed from bloXroute Cloud-API. It will compare the time each feed is providing a new transaction. A full readme is provided with the script. There are several important startup parameters that influence the script behavior with Infura and Alchemy:

Parameters:

  • — exclude-tx-contents:
    By default, the script will issue an eth_getTransactionByHash for each transaction returned in the script. These calls are avoided with the Cloud-API as the feed will return the content by default. However, we will run the script without content (even though most users will not use that option) in order to save requests and not get rate limited. The performance difference in real life will significantly favor the bloXroute stream because of the need to do a round trip for each transaction.
  • — min-gas-price
    Not all transactions are being propagated by the BDN — only transactions above a specific gas price. It is expected that the Infura/Alchemy feeds will contain more transactions (as it reports very low transactions). The script supports a startup parameter — min-gas-price to ignore transactions below a specified fee (allowing you to focus on more important transactions). However, the script needs the content of the transactions in order to check the gas price, and we want to avoid that in this setup. So, in our case we can’t use — min-gas-price since we want to use — exclude-tx-contents, and thus we will look only at transactions received on both feeds.

The script is expecting a parameter — ssl-dir that points to the certificate you obtained when registering your account.

Example

Below is an example of running the script for 10 minutes, comparing Infura and bloXroute’s Cloud-API without asking for content:

$ python compare_tx_feeds.py --eth wss://mainnet.infura.io/ws/v3/XXXXXXXXXX --use-cloud-api --ssl-dir /home/…/external_gateway/registration_only --interval 600 --num-intervals 1 --exclude-tx-contentsInitiating connection to: wss://eth.feed.blxrbdn.com:28333Initiating connection to: wss://mainnet.infura.io/ws/v3/XXXXXXXXXXwebsockets endpoint: wss://eth.feed.blxrbdn.com:28333 establishedwebsockets endpoint: wss://mainnet.infura.io/ws/v3/XXXXXXXXXX established — — — — — — — — — — — — — — — — — — — — — — — — — — -Interval: 600 seconds. End time: 2020–10–26 12:52:05. Minimum gas price: NoneAnalysis of Transactions received on both feeds:Number of transactions: 7533Number of transactions received from Gateway first: 6520Number of transactions received from Ethereum node first: 1013Percentage of transactions seen first from gateway: 86%Average time difference for transactions received first from gateway (ms): 83.8Average time difference for transactions received first from Ethereum node (ms): 213.1Total Transactions summary:Total tx from gateway: 7788Total tx from eth node: 26340Number of low fee tx ignored: 01 of 1 intervals complete. Exiting.

Here is the same test completed with Alchemy.

$ python compare_tx_feeds.py --eth wss://eth-mainnet.ws.alchemyapi.io/v2/XXXXXXXXXX --use-cloud-api --ssl-dir /home/…/external_gateway/registration_only --interval 600 --num-intervals 1 --exclude-tx-contentsInitiating connection to: wss://eth.feed.blxrbdn.com:28333Initiating connection to: wss://eth-mainnet.ws.alchemyapi.io/v2/XXXXXXXXXXwebsockets endpoint: wss://eth.feed.blxrbdn.com:28333 establishedwebsockets endpoint: wss://eth-mainnet.ws.alchemyapi.io/v2/XXXXXXXXXX established — — — — — — — — — — — — — — — — — — — — — — — — — — -Interval: 600 seconds. End time: 2020–10–26 13:27:45. Minimum gas price: NoneAnalysis of Transactions received on both feeds:Number of transactions: 4499Number of transactions received from Gateway first: 4494Number of transactions received from Ethereum node first: 5Percentage of transactions seen first from gateway: 99%Average time difference for transactions received first from gateway (ms): 2254.4Average time difference for transactions received first from Ethereum node (ms): 1450.4Total Transactions summary:Total tx from gateway: 4812Total tx from eth node: 28813Number of low fee tx ignored: 01 of 1 intervals complete. Exiting.

Understanding the Results

As explained above, it is expected that the node provider’s feed will contain many more transactions vs the BDN feed. This is because the BDN only propagates transactions above its current dynamic adjusted gas price limit. You should check the percentage of transactions received first from the BDN and the average time difference for transactions received first from the BDN/node provider. In the example above, 86% (from Infura test) and 99% (from Alchemy test) of the transactions were received first from the BDN with an average difference of 83ms and 2.2 sec, respectively.

Recall that people that use a feed from a node as a service provider likely need to request transaction content for each transaction hash, wasting valuable time. Using the BDN feeds, users can subscribe to receive content as part of the feed. Another important difference that results in time savings is the ability to filter transactions and get notifications only on transactions with specific criteria (such as addresses, values, etc.).

What about those that run their own node?

The scripts above will work with your own node and with a Local Gateway, assuming you installed one. We will publish results of a Local Gateway’s performance compared to a local node in a separate post.

Conclusion

The bloXroute BDN is fast. Users of node as a service providers will experience noticeable performance improvement using the BDN. Transactions submitted via the BDN will arrive to miners faster, and feeds (such as blocks and transactions) will provide notifications much faster. Users are encouraged to measure the performance difference themselves using the open sourced scripts detailed above. Users that want to take advantage of the BDN’s fast data highway can contact their node as a service provider or use the BDN directly.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store