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!
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 Step
s.
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.
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.
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 LoadNode
s 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
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.
All scripts are typescript files that can be run with ts-node
.
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.
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.
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.
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
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:
-
(If applicable)
createLedgerDuration*ledgerRate
CreateLedgerChannel steps are added with a timestamp randomly chosen between0
andcreateLedgerDuration
-
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 fromledger.timestamp+ledgerDelay
toduration
.If directly funded then the timestamp will be randomly selected from
0
toduration
. -
duration*CloseRate
close channel steps are added to the load file. For each step we randomly select a CreateChannel stepapp
and schedule a close step with a timestamp randomly selected fromapp.timestamp+closeDelay
toduration
.
Currently we used fixed outcome
and appData
s when creating channels.
We also do not support update channel steps yet.
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.
❯ 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.
Convenience utility that starts up ganache, two load nodes and runs a load file against them.