Skip to content
This repository has been archived by the owner on Oct 7, 2022. It is now read-only.

Latest commit

 

History

History
200 lines (137 loc) · 7.93 KB

File metadata and controls

200 lines (137 loc) · 7.93 KB

Quick Start

npx ts-node ./e2e-testing/scripts/load-generator.ts -o ./temp/sample_load.json -f Direct
npx ts-node ./e2e-testing/scripts/start-all.ts -l ./temp/sample_load.json

This generates a load file that uses Direct funding.

The start-all script then starts up ganache and two server wallets.

It then sends the generated load file that tells the wallets how many channels to create and close (and when to try and create them).

It then tells the nodes to start processing those instructions and waits for it to complete succesfully.

You should see something like this indicating that it ran succesfully.

[A] Updated job queue with 60 steps
[B] Updated job queue with 60 steps
[A] Starting job processing..
[A] This node will create 29 channel(s) using Direct funding
[B] Starting job processing..
[B] This node will create 31 channel(s) using Direct funding
[A] All jobs complete!
[B] All jobs complete!
SUCCESS!

Concepts

Load Node

There is a new class WalletLoadNode which is an http server that has its own wallet. The load node accepts a load file and runs the steps specified by the load file.

A LoadNode co-operates with it's peers by

  • letting peers know when a channel id has been created for a job file
  • sending the load file to peers
  • letting peers know when to start processing

This means you only have to interact with one LoadNode to load and run the load file.

If any error is returned from the serverWallet we stop the LoadNode process.

The /load endpoint can be used to load a load file. It accepts a POST request with a JSON body of Steps.

The /start endpoint is used to trigger processing of the steps in this and other nodes. It accepts a GET request. A response won't be returned until all jobs are completed and all our peer's jobs are completed as well. If an error occurs this returns a 500 error code with details on the error.

How Load is processed

Each step in the load file contains a timestamp value. We set a timeout with the timestamp value for each step. When the timer executes we attempt to create or close the channel as instructed.

Steps don't wait for the completion of previous steps before starting.

Load file

The load file is a list of instructions for a server wallet to perform. It looks something like this:

[ {
  "type": "CreateChannel",
  "jobId": "mushy-spicy-loose-uganda",
  "serverId": "B",
  "timestamp": 7641,
  "channelParams":"SNIPPED"
 },
  "type": "UpdateChannel",
  "serverId": "A",
  "jobId": "mushy-spicy-loose-uganda",
  "timestamp": 90933,
 "channelParams":"SNIPPED"
},
 {
  "type": "CloseChannel",
  "jobId": "mushy-spicy-loose-uganda",
  "serverId": "B",
  "timestamp": 142996
 },
]

The job id is used to represent a channel since we won't get a channel Id until the channel is actually created. The jobId is used by LoadNodes to know which channel instructions apply to.

The timestamp is when these instructions should be executed. The timestamp is an offset from when processing starts. So timestamp= 7641 is 7641 after the start of processing.

The serverId indicates which LoadNode is responsible for that step. Each LoadNode will have a unique serverId based on the entries in the role.config

Role Config

A simple JSON config file specifies various ports and private keys to be used for a LoadNode. This is used to easily start up LoadNodes without having to specify a bunch of different options.

Scripts

All scripts are typescript files that can be run with ts-node.

Sanity Checker

The sanity checker is a simple script that checks databases and ganache balances to make sure the correct amount of channels were created and the on-chain funds ended up where we thought.

The main argument it accepts is the load file to use. The sanity checker uses this to figure out how many channels we expect to see in the database (and in what status).

The sanity checker also checks the balance file outputed by start-ganache. It checks the destinations and contracts to perform a rough check of on-chain funds.

Start Ganache

This is similar to what we have in devtools but I wanted to avoid messing with env vars. It is responsible for starting ganache and deploying the contracts.

When the script stops running it saves the balances to a file, so we can easily check the final state of the chain.

Start Load Node

This starts up a load node server. The only required argument is the roleId (based on the roleConfig). Using the default role config the valid options are "A" or "B.

Load Generator

The load generator is responsible for generating load files. The load generator accepts arguments for

  • how often channels should be created/closed
  • how long channels should be created/closed
  • whether channels are funded using ledger channels or direct funding

Scheduling

The load generator uses a pretty basic scheduling algorithim.

Generally for each step type we add duration * rate steps to the load file with a timestamp randonly selected from 0 to duration.

The basic flow is:

  1. (If applicable) createLedgerDuration*ledgerRate CreateLedgerChannel steps are added with a timestamp randomly chosen between 0 and createLedgerDuration

  2. duration*CreateRate createChannel steps are added to the load file.

    If they ledger funded then we randomly select a CreateLedgerChannel ledger and generate a timestamp from ledger.timestamp+ledgerDelay to duration.

    If directly funded then the timestamp will be randomly selected from 0 to duration.

  3. duration*CloseRate close channel steps are added to the load file. For each step we randomly select a CreateChannel step app and schedule a close step with a timestamp randomly selected from app.timestamp+closeDelay to duration.

Limitations

Currently we used fixed outcome and appDatas when creating channels.

We also do not support update channel steps yet.

Direct Funding Example

npx ts-node ./e2e-testing/scripts/load-generator.ts -o ./temp/example.json -f  0.82s user 0.07s system 123% cpu 0.725 total
❯ npx ts-node ./e2e-testing/scripts/load-generator.ts -o ./temp/example.json -f Direct --createRate 5 --duration 30 --closeRate 0
[@statechannels/devtools] NODE_ENV is undefined — setting to "development"
Generating a test load file to  ./temp/example.json
Using the following options {
  outputFile: './temp/example.json',
  roleFile: './e2e-testing/test-data/roles.json',
  duration: 30,
  createRate: 5,
  closeRate: 0,
  closeDelay: 5,
  fundingStrategy: 'Direct'
}
150 channels will be created.
None of those channels will be closed.
Complete!

Here we are asking for a load file that will create 5 channels a second for 30 seconds. No channels will be closed. All channels will be directly funded.

Ledger Funding Example

❯ npx ts-node ./e2e-testing/scripts/load-generator.ts -o ./temp/ledger-example.json -f Ledger --createRate 1  --duration 30 --closeRate 0 --createLedgerDuration 5 --ledgerDelay 15
[@statechannels/devtools] NODE_ENV is undefined — setting to "development"
Generating a test load file to  ./temp/ledger-example.json
Using the following options {
  outputFile: './temp/ledger-example.json',
  roleFile: './e2e-testing/test-data/roles.json',
  duration: 30,
  createRate: 1,
  closeRate: 0,
  closeDelay: 5,
  fundingStrategy: 'Ledger'
}
Ledger options { ledgerDelay: 15, ledgerRate: 1, createLedgerDuration: 5 }
30 channels will be created.
None of those channels will be closed.
Complete!

Here we are asking for a load file that will create 1 channel a second for 30 seconds. No channels will be closed.

Ledger channels will be created for the first 5 seconds at the rate of 1 ledger channel a second. Any steps that depend on a ledger channel for funding will wait 15 seconds before attempting to use it.

Start All

Convenience utility that starts up ganache, two load nodes and runs a load file against them.