Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update to Neutron v5.0.0 #12

Open
wants to merge 34 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5206fcd
docs: make it more clear that a MNEMONIC is required to run the script
dib542 Apr 22, 2024
02262a4
docs: explain the local demo mnemonics source twice
dib542 Apr 22, 2024
1c464bd
docs: move mnenomic option documentation to one section
dib542 Apr 25, 2024
935c700
docs: explain the behavior of using FAUCET_MNEMONIC at simulation end
dib542 Apr 25, 2024
e9aa736
docs: shorten line lengths to under 120 characters
dib542 Apr 25, 2024
15d9165
docs: move TOKEN_CONFIG and PAIR_CONFIG docs to README file
dib542 Apr 25, 2024
40a1fa0
docs: make TOKEN_CONFIG option header larger
dib542 Apr 25, 2024
414fe0c
style: make whitespace more consistent
dib542 Apr 25, 2024
7625658
feat: move most env vars to an .env file
dib542 May 6, 2024
ecd55bd
feat: move TOKEN_CONFIG_DEFAULT to local TOKEN_CONFIG example
dib542 May 6, 2024
e0390c7
docs: note default TRADE_FREQUENCY_SECONDS value
dib542 May 6, 2024
1b33b8d
feat: set default BOT_RAMPING_DELAY outside of docker compose env
dib542 May 6, 2024
a80ebb4
feat: make DOCKER_ENV var optional when run outside of docker-compose
dib542 May 6, 2024
40a19c9
feat: add SKIP_DEPOSIT option
dib542 May 6, 2024
89e1cea
fix: ensure to fetch up to date tags of the Neutron git repo
dib542 Jul 3, 2024
ffabb03
fix: new (SDK50) setup doesn't support setting GRPCWEB address
dib542 Jul 3, 2024
1c7b983
fix: ensure local DOCKER_ENV can still be read if HOSTNAME is set
dib542 Jul 3, 2024
3a341a5
feat: allow tokens of different decimal exponent to have correct price
dib542 Jul 3, 2024
484f6d5
fix: spelling
dib542 Jul 3, 2024
cfaeeca
docs: add more detail to placed trade logs
dib542 Jul 3, 2024
2f88553
fix: allow trade amount to be increased to required minimum amount
dib542 Jul 3, 2024
c16963e
fix: bc needs a herestring to read a string
dib542 Jul 3, 2024
3d1631b
fix: spaces
dib542 Jul 3, 2024
93d2003
fix: price direction to be consistent with pair_display_price direction
dib542 Jul 3, 2024
eaa8df7
feat: tag neutron-node with current version
dib542 Oct 17, 2024
0e7a35d
fix: allow Docker compose service to be built without heighliner image
dib542 Oct 18, 2024
47f6a5f
chore: update Docker CLI version
dib542 Oct 18, 2024
92b7e8b
refactor: use recommended CMD syntax
dib542 Oct 18, 2024
8541114
feat: add more checking delay: startup is a bit slower now
dib542 Oct 18, 2024
b301e38
feat: update to most current production release
dib542 Oct 18, 2024
db52a2b
feat: update to Neutron v5 API
dib542 Oct 18, 2024
71a660e
feat: only delay loops after the first loop
dib542 Oct 18, 2024
2429d21
fix: increment loop properly
dib542 Nov 19, 2024
71a945c
fix: the closest piece of liquidity may be a pool or a limit order
dib542 Nov 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .env.local.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# works with local chain from `make build-neutron ...`
CHAIN_ID=test-1
RPC_ADDRESS=http://0.0.0.0:26657
API_ADDRESS=http://0.0.0.0:1317
GAS_PRICES=0.0025untrn
GAS_ADJUSTMENT=2
TRADE_FREQUENCY_SECONDS=60
# this token config demonstrates several ways to define price and other vars
# use range of token amounts to visualize multiple orders of magnitude in dev UI
TOKEN_CONFIG='
{
"10000000000000uibcusdc<>10000000000000uibcatom": 10,
"100000000000uibcusdc<>100000000000untrn": {
"price": 2,
"ticks": 50
},
"defaults": {
"fees": [0,1,2,3,4,5,10,20,50,100,150,200],
"gas": "1000000000untrn"
}
}
'
# this mnemonic is defined in the default local setup: https://github.com/neutron-org/neutron/blob/v3.0.0/network/init.sh#L19-L21
FAUCET_MNEMONIC=veteran try aware erosion drink dance decade comic dawn museum release episode original list ability owner size tuition surface ceiling depth seminar capable only
# test the pool withdrawal mechanism to return tokens to the faucet with:
ON_EXIT_WITHDRAW_POOLS=1
18 changes: 18 additions & 0 deletions .env.testnet.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# works with testnet, for current information check https://github.com/cosmos/chain-registry/blob/master/neutron/chain.json
CHAIN_ID=pion-1
RPC_ADDRESS=https://rpc-lb-pion.ntrn.tech:443
API_ADDRESS=https://rest-lb-pion.ntrn.tech:443
GAS_PRICES=0.025untrn
GAS_ADJUSTMENT=2
# it is helpful to see multiple swaps per minute for more realistic minute candles of a price timeseries chart
TRADE_FREQUENCY_SECONDS=20
# use demo pair amount from demo faucet and untrn amount from pion-1 faucet
TOKEN_CONFIG={"10000000factory/neutron19glux3jzdfyyz6ylmuksgxfj5phdaxfr2uhy86/factoryATOM<>10000000factory/neutron19glux3jzdfyyz6ylmuksgxfj5phdaxfr2uhy86/factoryNTRN":{"price":"coingecko:usd-coin<>neutron-3","ticks":80,"deposit_accuracy":100,"swap_accuracy":5,"gas":"2000000untrn"}}
# add credentials of accounts
COINGECKO_API_TOKEN=
MNEMONIC=

# note: consider using SKIP_INITIAL_DEPOSIT=1 when starting / restarting a testnet bot
# a testnet bot may need to be restarted often and we don't want to repeat
# the initial deposit. the initial deposit can be made and adjusted at
# any time through the UI at https://app.testnet.duality.xyz/
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ keystore.db
contracts/artifacts/
contracts/*.wasm

# env
.env

# IDEs
*.iml
.idea
Expand Down
22 changes: 13 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
# Use neutron binary version given through version number or heighliner image
# eg. passing a locally made heighliner image as NEUTRON_IMAGE
ARG NEUTRON_VERSION
# Use Heighliner build by default to get around building for correct platform issue
# as Heighliner build support multiple platforms. More details in commit message
ARG NEUTRON_IMAGE=ghcr.io/strangelove-ventures/heighliner/neutron:${NEUTRON_VERSION}
ARG NEUTRON_VERSION=latest

FROM "$NEUTRON_IMAGE" as neutrond-binary
# the neutron binary image is typically built on amd64 (but may be changed)
# see: https://github.com/neutron-org/neutron/blob/v5.0.0-rc0/Makefile#L107-L122
ARG BUILDPLATFORM=amd64

# optionally specify a difference image to get the binary from
ARG NEUTRON_IMAGE=neutron-${BUILDPLATFORM}:${NEUTRON_VERSION}

# make build platform consistent across images to avoid docker.io lookup error
# see: https://stackoverflow.com/questions/20481225/how-can-i-use-a-local-image-as-the-base-image-with-a-dockerfile#69798220
FROM --platform=${BUILDPLATFORM} ${NEUTRON_IMAGE} AS neutrond-binary

# allow this container to contact other Docker containers through the docker CLI
FROM docker:24.0.5-cli
FROM --platform=${BUILDPLATFORM} docker:27.3.1-cli

# add additional dependencies for the testnet scripts
RUN apk add bash curl grep jq;
Expand All @@ -18,4 +22,4 @@ COPY --from=neutrond-binary /bin/neutrond /usr/bin
WORKDIR /workspace/neutron
COPY scripts /workspace/neutron/scripts

CMD bash ./scripts/run_trade_bot.sh
CMD ["bash", "./scripts/run_trade_bot.sh"]
14 changes: 10 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

REPOS_DIR ?= ./repos
SETUP_DIR ?= $(REPOS_DIR)/neutron-integration-tests/setup
DOCKER ?= docker
COMPOSE ?= docker-compose
NEUTRON_VERSION ?= v2.0.2
NEUTRON_VERSION ?= v5.0.0-rc0
GAIA_VERSION ?= v14.1.0


Expand All @@ -18,7 +19,7 @@ init-neutron:
ifeq (,$(wildcard $(REPOS_DIR)/neutron))
cd $(REPOS_DIR) && git clone -b $(NEUTRON_VERSION) https://github.com/neutron-org/neutron.git
else
cd $(REPOS_DIR)/neutron && git fetch origin $(NEUTRON_VERSION) && git checkout $(NEUTRON_VERSION)
cd $(REPOS_DIR)/neutron && git fetch origin $(NEUTRON_VERSION) && git fetch origin $(NEUTRON_VERSION) --tags && git checkout $(NEUTRON_VERSION)
endif

init-hermes:
Expand Down Expand Up @@ -52,6 +53,11 @@ build-gaia: init-dir init-gaia

build-neutron: init-dir init-neutron
cd $(REPOS_DIR)/neutron && $(MAKE) build-docker-image
docker tag neutron-node:latest neutron-node:$(NEUTRON_VERSION)

build-neutron-static-linux-amd64: init-dir init-neutron
cd $(REPOS_DIR)/neutron && $(MAKE) build-static-linux-amd64
docker tag neutron-amd64:latest neutron-amd64:$(NEUTRON_VERSION)

build-hermes: init-dir init-hermes
cd $(SETUP_DIR) && $(MAKE) build-hermes
Expand Down Expand Up @@ -83,8 +89,8 @@ clean:

# --- new docker compose network commands ---

build-trade-bot:
@$(COMPOSE) build --build-arg NEUTRON_VERSION=$(NEUTRON_VERSION)
build-trade-bot: build-neutron-static-linux-amd64
@$(DOCKER) build . -t dex-trading-bot:$(NEUTRON_VERSION) --build-arg NEUTRON_VERSION=$(NEUTRON_VERSION)

start-trade-bot: build-trade-bot
@$(COMPOSE) up
Expand Down
93 changes: 82 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,47 @@ To run the bot, you will first need a chain to run the bot against,
locally this should be a single dockerized neutron node
- `make build-neutron`

To run the default setup of a single neutron-node chain and a single trading bot:
- `make start-trade-bot`
To run the default setup of a single neutron-node chain and a single trading bot with a single wallet:
- `make start-trade-bot MNEMONIC=...`
- the available `MNENOMIC` options are explained in the [Options section](#mnemonic-options)

This composed neutron chain and trading bot network will persist until you call:
- `make stop-trade-bot`

### Test runs (start+stop)
You can test a chain and bot(s) configuration and exit with cleanup in one step using:
- `make test-trade-bot`
- `make test-trade-bot MNEMONIC=...`

However the default settings are quite conservative, and won't product many txs.
A larger test which should generate approximately ~1000-2000 txs in ~6 minutes with 30 bots could be done with:
- `make test-trade-bot BOTS=30 BOT_RAMPING_DELAY=5 TRADE_FREQUENCY_SECONDS=0 TRADE_DURATION_SECONDS=180`
- `make test-trade-bot BOTS=30 BOT_RAMPING_DELAY=5 TRADE_FREQUENCY_SECONDS=0 TRADE_DURATION_SECONDS=180 MNEMONIC=...`

This can be ideal for CI type testing of a service that depends on Dex transactions on a Neutron chain.
But if you want the chain to persist after the trades are completed (with a finite `TRADE_DURATION_SECONDS`),
then `make start-trade-bot` should be used instead.

## Available options

### Mnemonic options
A single mnenomic option must be used to run `make start-trade-bot` or `make test-trade-bot` this may be in the form of:
- a list of mnemonics to be used (delimited with any `\r\n,;` characters) where one mnemonic is given to each bot.
An error will be thrown if not enough mnemonics are provided for the number of `BOTS` requested.
- `MNEMONIC`
- `MNEMONICS`
- `BOT_MNEMONIC`
- `BOT_MNEMONICS`
- a single mnenomic which will be used to like a faucet to fund a separate randomly generated wallet for each bot
(so you may easily run more than one bot with one wallet).
- `FAUCET_MNEMONIC`
- on simulation end: the remaining token balance will be refunded to the faucet wallet.
- you should strongly consider using `ON_EXIT_WITHDRAW_POOLS=1` when using this option on a testnet.
If the pools are not withdrawn and you have not saved the randomly generated mnenomics for each bot
then ***you will lose access to these deposited tokens***.
- if you are running a local chain you can use the DEMO_MNEMONICs from the neutron repo
[networks/init.sh](https://github.com/neutron-org/neutron/blob/v3.0.0/network/init.sh#L19-L21) file for these settings.

### Optional options

All docker-compose env vars are able to be set in both `make start-trade-bot` and `make test-trade-bot`
- Chain variables
- `CHAIN_ID`: the chain ID
Expand All @@ -47,18 +68,68 @@ All docker-compose env vars are able to be set in both `make start-trade-bot` an
- `ON_EXIT_WITHDRAW_POOLS`: if set, withdraw all user's Dex pools after TRADE_DURATION_SECONDS
- `GAS_ADJUSTMENT`: how much more than the base estimated gas price to pay for each tx
- `GAS_PRICES`: calculate how many fees to pay from this fraction of gas
- `TOKEN_CONFIG`: a token pairs configuration (JSON) object for eg. token amounts to trade
- see [helpers.sh](https://github.com/neutron-org/dex-trading-bot/blob/131a5f1590483840305cb475f8a867996509333e/scripts/helpers.sh#L41-L63) for more setting details
- mnemonics:
- `FAUCET_MNEMONIC` (optional): the mnemonic of the account that will fund generated bots
- `BOT_MNEMONIC/S` or `MNEMONIC/S` (optional): the mnemonics for self-funded bot account(s)
- at least one of `FAUCET_MNEMONIC` or `BOT_/MNEMONIC/S` should be provided
- with a local chain you can use `DEMO_MNEMONIC`s from the neutron networks/init.sh file
- `TOKEN_CONFIG`: a token pairs configuration (JSON) object to specify trading behavior to use for each token pair
- see the [TOKEN_CONFIG option section](#token_config-option) for more details
- `COINGECKO_API_TOKEN`: a Coingecko API token used for live prices fetching. Only used with respective token pair price setting. The token should be a [demo API token](https://www.coingecko.com/en/api/pricing). Pro tokens aren't supported because they use different endpoints. Keep in mind the very limited request rate the demo tokens provide when configuring the bots number and trading intensity.

eg. `make start-trade-bot BOTS=30 BOT_RAMPING_DELAY=5 TRADE_FREQUENCY_SECONDS=0 TRADE_DURATION_SECONDS=450 MNEMONIC=...`
will start a persistent chain that for the first ~10min (7min+ramping) will generate ~5000txs using 30 bots.

### TOKEN_CONFIG option

format for TOKEN_CONFIG is:
```
TOKEN_CONFIG = {
"amountAtokenA<>amountBtokenB": numeric_price_or_PAIR_CONFIG_object,
"defaults": PAIR_CONFIG
}
```
the object keys are the usable tokens for each pair (to be shared across all bots),
the object values are the price ratio of tokenB/tokenA, a coingecko pair or a config object: (default values are listed)
```
PAIR_CONFIG = {
"price": 1, # price ratio is of tokenB/tokenA (how many tokenA is required to buy 1 tokenB?), OR
"price": "coingecko:api_idA<>api_idB", # for live price retrieval, use the coingecko API IDs of the tokens (e.g. "coingecko:cosmos<>neutron-3" for atom<>ntrn pair)
"price_decimals": [0, 0] # the display token decimals (exponents) over base token amounts (eg. for ETH=10^18wei, USDC=10^6uUSDC use [18, 6])
"ticks": 100, # number of ticks for each bot to deposit
"fees": [1, 5, 20, 100] # each LP deposit fee may be (randomly) one of the whitelisted fees here
"gas": "0untrn" # additional gas tokens that bots can use to cover gas fees
"rebalance_factor": 0.5, # fraction of excessive deposits on either pair side to rebalance on each trade
"deposit_factor": 0.5, # fraction of the recommended maximum reserves to use on a single tick deposit
"swap_factor": 0.5, # max fraction of a bot's token reserves to use on a single swap trade (max: 1)
"swap_accuracy": 100, # ~1% of price: swaps will target within ~1% of current price
"deposit_accuracy": 1000, # ~10% of price: deposits will target within ~10% of current price
"amplitude1": 5000, # ~50% of price: current price will vary by ~50% of set price ratio
"period1": 36000, # ten hours: current price will cycle min->max->min every ten hours
"amplitude2": 1000, # ~10% of price: current price will vary by an additional ~10% of price ratio
"period2": 600, # ten minutes: current price will cycle amplitude2 offset every ten minutes
}
```

For example the following `TOKEN_CONFIG` option sets each bot to trade on 3 pools
- the first `uibcusdc<>uibcatom` with all default options except price of `1uibcatom = 10uibcusdc`
- the second `untrn<>uibcusdc` with custom GoinGecko pricing and specified 50 deposited ticks
- the third `untrn<>uibcatom` with custom sinusoidal pricing around a price of `1uibcatom = 5untrn`
- all pools will operate with the specified `defaults` values of `fees` and `gas`
```js
TOKEN_CONFIG = {
"10000000000000uibcusdc<>10000000000000uibcatom": 10,
"100000000000untrn<>100000000000uibcusdc":{
"price": "coingecko:neutron-3<>usd-coin",
"price_decimals": [6, 6], # not required here (no decimal difference)
"ticks": 50
},
"1000000000uibcatom<>1000000000untrn":{
"price": 5,
"amplitude2": 100
},
"defaults":{
"fees": [0,1,2,3,4,5,10,20,50,100,150,200],
"gas": "1000000000untrn"
}
}
```

# Troubleshooting

The chain should be visible at http://localhost:26657 and REST at http://localhost:1317.
Expand Down
46 changes: 11 additions & 35 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: '3.8'
services:
neutron-node:
image: neutron-node
image: neutron-node:${NEUTRON_VERSION:-latest}
command: >
/bin/bash -c '
#!/bin/bash
Expand All @@ -22,8 +22,7 @@ services:
--log_level "$$LOG_LEVEL" \
--home "$$CHAIN_DIR" \
--pruning=nothing \
--grpc.address="0.0.0.0:$$GRPCPORT" \
--grpc-web.address="0.0.0.0:$$GRPCWEB"
--grpc.address="0.0.0.0:$$GRPCPORT"
'
container_name: neutron-node
volumes:
Expand All @@ -45,49 +44,26 @@ services:
dex-trading-bot:
build:
context: .
args:
BUILDPLATFORM: ${BUILDPLATFORM:-amd64}
NEUTRON_VERSION: ${NEUTRON_VERSION:-latest}
image: dex-trading-bot:${NEUTRON_VERSION:-latest}
platform: linux/amd64
depends_on:
- "neutron-node"
entrypoint: ["/bin/bash", "./scripts/setup_entrypoint.sh"]
command: ["/bin/bash", "./scripts/run_trade_bot.sh"]
deploy:
replicas: ${BOTS:-1}
env_file:
- ${ENV_FILE:-.env}
environment:
- BOT_RAMPING_DELAY=${BOT_RAMPING_DELAY:-3} # seconds between starting each bot
# override env file with variables that connect to the neutron-node service here
- CHAIN_ID=${CHAIN_ID:-test-1}
- RPC_ADDRESS=${RPC_ADDRESS:-http://neutron-node:26657}
- API_ADDRESS=${API_ADDRESS:-http://neutron-node:1317}
# this var is set when using `make test-trade-bot`
- TRADE_DURATION_SECONDS=${TRADE_DURATION_SECONDS:-}
- TRADE_FREQUENCY_SECONDS=${TRADE_FREQUENCY_SECONDS:-60}
- ON_EXIT_WITHDRAW_POOLS=${ON_EXIT_WITHDRAW_POOLS:-}
- GAS_ADJUSTMENT=${GAS_ADJUSTMENT:-2}
- GAS_PRICES=${GAS_PRICES:-0.0025untrn}
# optional faucet mnemonic should be set with specific FAUCET_MNEMONIC:
- FAUCET_MNEMONIC=${FAUCET_MNEMONIC}
# optional bot mnemonics can be set using BOT_MNEMONIC/S or MNEMONIC/S:
# mnemonics may be delimited with: line breaks, tabs, semicolons, commas, and multiple spaces
- MNEMONICS=${MNEMONICS:-$MNEMONIC}
- BOT_MNEMONICS=${BOT_MNEMONICS:-$BOT_MNEMONIC}
# allow passing through a TOKEN_CONFIG object, defaulting to TOKEN_CONFIG_DEFAULT if not found
- TOKEN_CONFIG=${TOKEN_CONFIG}
# use (from default local node test wallets) up to about 10,000,000 (display) tokens in each pool
# use range of token amounts to visualize multiple orders of magnitude in dev UI
- TOKEN_CONFIG_DEFAULT=
{
"10000000000000uibcusdc<>10000000000000uibcatom":10,
"100000000000uibcusdc<>100000000000untrn":{
"price":2,
"ticks":50
},
"1000000000uibcatom<>1000000000untrn":{
"price":0.2,
"ticks":30
},
"defaults":{
"fees":[0,1,2,3,4,5,10,20,50,100,150,200],
"gas":"1000000000untrn"
}
}
- COINGECKO_API_TOKEN=${COINGECKO_API_TOKEN}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
Expand Down
2 changes: 1 addition & 1 deletion scripts/check_chain_status.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ abci_info=$(
--max-time 3 \
--retry 30 \
--retry-connrefused \
--retry-delay 1 \
--retry-delay 2 \
--silent \
$RPC_ADDRESS/abci_info
)
Expand Down
Loading