As a EOS smart-contract developer I need plain and simple API to manage local testnets.
- I need API to start and stop a testnet and query its status.
- I may want to start more then one testnet (eg. in CI environments)
- Testnets created with EOS Factory should be isolated from each other and should not interfere with a testnet I may have spawned on my own using stardard EOS tools.
Below is an example and of how new API (let's call it EOS Factory 2.0 for the time being) could feel like. It should be considered a starting point for a discussion with the EOS community about how ideal API for testing smart-contract should look like and what features should it provide. Everyone is welcome to contribute proposition, opinion and - what would be most valuable - describe real-live use cases. Let's discuss the idea and try to specify the API in comments.
import eosfactory as eosf
cfg = eosf.TestnetCfg(
http_server_address = "127.0.0.1:8888",
data_dir = "/home/user/myproject/localnode/",
config_dir = "/home/user/myproject/localnode/",
chain_state_db_size_mb = "200",
contracts_console = True,
verbose_http_errors = True,
enable_stale_production = True,
producer_name = "eosio",
signature_provider = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3",
plugins = ["eosio::producer_plugin", "eosio::chain_api_plugin", "eosio::http_plugin", "eosio::history_api_plugin" ],
genesis_json = "/home/user/myproject/localnode/genesis.json",
delete_all_blocks = True,
)
cmd = eosf.nodeos_cmd(cfg)
process = eosf.run_cmd_async(
cmd,
redirect_to_file=cfg.file_in_workspace('output.log'),
)
# some interaction with the network here
# ...
retcode = eosf.kill_and_wait(process)
Testnet configuration
eosf.TestnetCfg is a constructor of a testnet configuration.
Options used in the above example were taken from a command line used by EOS Factory to spawn nodeos processes and should be considered only as an example and not an exhaustive list of all the options.
All the options supported by EOS Factory should have reasonable default values. For example:
- For network addresses - if not specified,
localhost should be used
- For port numbers - if not specified, an unused number from documented range should be taken
- For paths - if not specified, random not existing folder under
/tmp should be used (e.g. /tmp/eosf-XXXXX where XXXXX is a random number)
Why separate configuration from the actual command
The testnet on its own is of no use. It brings a value only if we can interact with it, for example, to create a user account and its keys or to deploy a smart-contract. To support those interactions, we will have separate APIs, and we need an easy way to configure them to work with a specified testnet.
Below is an example of how this other APIs could use testnet configuration (note: this is just an example and not specification - we will have a discussion on this in a separate issue):
import eosfactory as eosf
eosf.cleos_for_net(testnet_cfg).deploy_smart_contract(....)
The other example of configuration object usage is a cfg.file_in_workspace function from the first listing. It creates a path to file in a folder where other data related to given testnet reside.
Why separate command from its execution
The cmd value returned from nodeos_cmd function in the first example above is a sequence of nodeos arguments (first item of which is a path to binary itself) suitable to be used as the first argument to Popen constructor from Python standard subprocess module. This way developer can have full control over how nodeos is executed.
We should also provide convenient functions to execute and manage EOS binaries. One of such function is eosf.run_cmd_async(). It uses Popen internally to hide some nasty details from smart-contract developers (like the need for pipelines creation). It could also wait for nodeos to become responsive (i.e. ready to serve requests) before it returns execution. eosf.kill_and_wait() is another one, that sends a TERM signal to a process, waits for it to stop and returns its status code.
As a EOS smart-contract developer I need plain and simple API to manage local testnets.
Below is an example and of how new API (let's call it EOS Factory 2.0 for the time being) could feel like. It should be considered a starting point for a discussion with the EOS community about how ideal API for testing smart-contract should look like and what features should it provide. Everyone is welcome to contribute proposition, opinion and - what would be most valuable - describe real-live use cases. Let's discuss the idea and try to specify the API in comments.
Testnet configuration
eosf.TestnetCfgis a constructor of a testnet configuration.Options used in the above example were taken from a command line used by EOS Factory to spawn
nodeosprocesses and should be considered only as an example and not an exhaustive list of all the options.All the options supported by EOS Factory should have reasonable default values. For example:
localhostshould be used/tmpshould be used (e.g./tmp/eosf-XXXXXwhere XXXXX is a random number)Why separate configuration from the actual command
The testnet on its own is of no use. It brings a value only if we can interact with it, for example, to create a user account and its keys or to deploy a smart-contract. To support those interactions, we will have separate APIs, and we need an easy way to configure them to work with a specified testnet.
Below is an example of how this other APIs could use testnet configuration (note: this is just an example and not specification - we will have a discussion on this in a separate issue):
The other example of configuration object usage is a
cfg.file_in_workspacefunction from the first listing. It creates a path to file in a folder where other data related to given testnet reside.Why separate command from its execution
The
cmdvalue returned fromnodeos_cmdfunction in the first example above is a sequence ofnodeosarguments (first item of which is a path to binary itself) suitable to be used as the first argument toPopenconstructor from Python standardsubprocessmodule. This way developer can have full control over hownodeosis executed.We should also provide convenient functions to execute and manage EOS binaries. One of such function is
eosf.run_cmd_async(). It usesPopeninternally to hide some nasty details from smart-contract developers (like the need for pipelines creation). It could also wait fornodeosto become responsive (i.e. ready to serve requests) before it returns execution.eosf.kill_and_wait()is another one, that sends a TERM signal to a process, waits for it to stop and returns its status code.