Skip to content
This repository has been archived by the owner on Jun 17, 2024. It is now read-only.

Latest commit

 

History

History
75 lines (60 loc) · 5.68 KB

e2e.md

File metadata and controls

75 lines (60 loc) · 5.68 KB

Introduction

The tests used by each chain specific bridge differ significantly even though the core tests should remain the same for the BTP protocol. This introduces discrepancies across branches that are hard to track. Therefore, there is a need for a unified testing framework, specifically an end-to-end testing framework with the core set of tests shared across each individual BTP integration.

Terminology

Term Definition Link
EventID Event log generated by BTS Smart contract includes an identifier (serial number) that represents the transaction it was generated on -

Considerations

Chain API

  1. Verified Events: Each Chain API implementation should ensure that the event log received is true. This can be ensured either by using a block and receipt verification logic specific to that chain.
  2. Network Latency: The user or caller of chain API will expect the response from request or subscription APIs within a reasonable time period. A significant delay in processing time either by relay or the chains themselves would mean the calling functions reach timeout.
  3. Chain Specific Parameters: A chain can be susceptible to dynamic parameters, like rpc rate limit, block time and gas price, which can affect the execution of transaction. Adjusting these parameters can themselves be tricky.

Interface

  1. Sufficiency: The arguments required to perform basic functionalities should be sufficient for all chains. For example, sender’s private key, recipient BTP address, amount and coin name are the arguments which should be sufficient for executing a “Transfer” call for any chain. This is necessary to ensure that a common API is followed.

Test Runs

  1. Environment: The test runs can exhibit some difference in behavior based on which network they are being run on. For example, a local development environment is very less likely to have gas price fluctuations and network delays. As such, a script should consider the generic behavior of the environment it’s running its tests upon.
  2. Funds The funds necessary to make extensive tests may not be always available for testnet or mainnet

Design

This section is broken down into subsections, each focusing on a specific module that combines to form the overall system.

Chain API Subscription Client

  1. Subscriber: Chain API receives input configuration that includes contract address, whose event logs are to be collected. The collection can be done either by subscribing to a websocket connection provided by the blockchain or by polling for new blocks with rpc calls.
  2. Decoder: Format of received event logs is chain dependent e.g. event logs are rlp-encoded in the case of harmony chain, while they are in clean text in the case of icon chain. As such these event logs must be decoded so that relevant fields in the event log can be extracted.
  3. Filter: Amongst all the decoded event logs are the ones which include information pertaining to the transaction that we have executed. For example, the type of event log and an identifier denoting the transaction could be the information we seek in the event log. This identification of the matching event log is done by a matching (or filter) module.

Chain API RPC Client RPC Client only serves to provide a set of helper functions that can be used to execute calls like querying for balance, sign and send transactions, call methods of a smart-contract, etc. The parameters necessary for the RPC call e.g. gas limit, gas price should be appropriately selected.

Chain Agnostic Interface The interface provides a set of functions that are necessary for executing transactions on a chain. It should include functions for the following tasks:

  • Transaction related requests like querying balance, transfer coin to an address, get transaction receipt
  • Subscription related requests like watch for a specific event id of a specific event type generated by a contract address
  • Account related requests like getting wallet addresses, BTP address

Test Runner

The test runner executes scripts, each of which are written to test a specific case. Along with the chain interface, it also includes a set of helper scripts that eases writing the tests. A pseudocode of a script to do a transaction is as follows.

def transfer_with_approve(srcClient, dstClient, coin, testSuite):
    srcKey, srcAddress = srcClient.GetKeyPairs()
    dstKey, dstAddress = dstClient.GetKeyPairs()
    amount = 1e18 
    if coin != srcClient.NativeCoin():
	srcClient.Approve(coin, srcKey, dstAddress, amount)
   txnHash = srcClient.Transfer(coin, srcKey, dstAddress, amount)
   isTestPass = testSuite.WaitForEvents(txnHash, [
        “TransferReceived”:() => return true,
        “TransferEnd”: (code) => if code==OK return true else false
    ])
    return isTestPass
def transfer_less_than_fee(srcClient, dstClient, coin, testSuite):
    srcKey, srcAddress = srcClient.GetKeyPairs()
    dstKey, dstAddress = dstClient.GetKeyPairs()
    amount = testSuite.getFeeCharged() - 1 
    if coin != srcClient.NativeCoin():
        srcClient.Approve(coin, srcKey, dstAddress, amount)
   txnHash = srcClient.Transfer(coin, srcKey, dstAddress, amount)
   isTestPass = testSuite.WaitForEvents(txnHash, [
       “TransferReceived”:() => return true,
      “TransferEnd”: (code) => if code==ERR return true else false
    ])
    return isTestPass

e2e5