From 47f1a6564b023b598b4b8ca996fa96fd997dd547 Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Fri, 5 Jul 2024 16:26:19 +0300 Subject: [PATCH] slinky's market map generation in genesis --- network/init-neutrond.sh | 24 +++++++++- network/slinky_genesis.go | 99 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 network/slinky_genesis.go diff --git a/network/init-neutrond.sh b/network/init-neutrond.sh index 563572a2b..fc1418c7b 100755 --- a/network/init-neutrond.sh +++ b/network/init-neutrond.sh @@ -53,6 +53,12 @@ CW4_GROUP_CONTRACT=$THIRD_PARTY_CONTRACTS_DIR/cw4_group.wasm NEUTRON_CHAIN_MANAGER_CONTRACT=$CONTRACTS_BINARIES_DIR/neutron_chain_manager.wasm +# Slinky genesis configs +USE_CORE_MARKETS=true +USE_RAYDIUM_MARKETS=false +USE_UNISWAPV3_BASE_MARKETS=false +USE_COINGECKO_MARKETS=false + echo "Add consumer section..." $BINARY add-consumer-section --home "$CHAIN_DIR" ### PARAMETERS SECTION @@ -719,12 +725,28 @@ function convert_bech32_base64_esc() { DAO_CONTRACT_ADDRESS_B64=$(convert_bech32_base64_esc "$DAO_CONTRACT_ADDRESS") echo $DAO_CONTRACT_ADDRESS_B64 +echo "Adding marketmap into genesis..." +go run network/slinky_genesis.go --use-core=$USE_CORE_MARKETS --use-raydium=$USE_RAYDIUM_MARKETS --use-uniswapv3-base=$USE_UNISWAPV3_BASE_MARKETS --use-coingecko=$USE_COINGECKO_MARKETS --temp-file=markets.json +MARKETS=$(cat markets.json) + +NUM_MARKETS=$(echo "$MARKETS" | jq '.markets | length + 1') + +NUM_MARKETS=$NUM_MARKETS; jq --arg num "$NUM_MARKETS" '.app_state["oracle"]["next_id"] = $num' "$GENESIS_PATH" > genesis_tmp.json && mv genesis_tmp.json "$GENESIS_PATH" +MARKETS=$MARKETS; jq --arg markets "$MARKETS" '.app_state["marketmap"]["market_map"] = ($markets | fromjson)' "$GENESIS_PATH" > genesis_tmp.json && mv genesis_tmp.json "$GENESIS_PATH" +jq '.app_state["marketmap"]["last_updated"] = 1' "$GENESIS_PATH" > genesis_tmp.json && mv genesis_tmp.json "$GENESIS_PATH" +MARKETS=$MARKETS; jq --arg markets "$MARKETS" '.app_state["oracle"]["currency_pair_genesis"] += [$markets | fromjson | .markets | values | .[].ticker.currency_pair | {"currency_pair": {"Base": .Base, "Quote": .Quote}, "currency_pair_price": null, "nonce": 0} ]' "$GENESIS_PATH" > genesis_tmp.json && mv genesis_tmp.json "$GENESIS_PATH" +MARKETS=$MARKETS; jq --arg markets "$MARKETS" '.app_state["oracle"]["currency_pair_genesis"] |= (to_entries | map(.value += {id: (.key + 1)} | .value))' "$GENESIS_PATH" > genesis_tmp.json && mv genesis_tmp.json "$GENESIS_PATH" + +cat markets.json + +rm markets.json + +echo "Setting the rest of Neutron genesis params..." set_genesis_param admins "[\"$NEUTRON_CHAIN_MANAGER_CONTRACT_ADDRESS\"]" # admin module set_genesis_param treasury_address "\"$DAO_CONTRACT_ADDRESS\"" # feeburner set_genesis_param fee_collector_address "\"$DAO_CONTRACT_ADDRESS\"," # tokenfactory set_genesis_param security_address "\"$SECURITY_SUBDAO_CORE_CONTRACT_ADDRESS\"," # cron set_genesis_param limit 5 # cron -#set_genesis_param allow_messages "[\"*\"]" # interchainaccounts set_genesis_param signed_blocks_window "\"$SLASHING_SIGNED_BLOCKS_WINDOW\"," # slashing set_genesis_param min_signed_per_window "\"$SLASHING_MIN_SIGNED\"," # slashing set_genesis_param slash_fraction_double_sign "\"$SLASHING_FRACTION_DOUBLE_SIGN\"," # slashing diff --git a/network/slinky_genesis.go b/network/slinky_genesis.go new file mode 100644 index 000000000..7bd26227f --- /dev/null +++ b/network/slinky_genesis.go @@ -0,0 +1,99 @@ +// copypasted from: https://github.com/skip-mev/slinky/blob/main/scripts/genesis.go + +package main + +import ( + "flag" + "fmt" + + "github.com/skip-mev/slinky/cmd/constants" + mmtypes "github.com/skip-mev/slinky/x/marketmap/types" +) + +var ( + useCore = flag.Bool("use-core", false, "use core markets") + useRaydium = flag.Bool("use-raydium", false, "use raydium markets") + useUniswapV3Base = flag.Bool("use-uniswapv3-base", false, "use uniswapv3 base markets") + useCoinGecko = flag.Bool("use-coingecko", false, "use coingecko markets") + tempFile = flag.String("temp-file", "markets.json", "temporary file to store the market map") +) + +func main() { + // Based on the flags, we determine what market.json to configure. By default, we use Core markets. + // If the user specifies a different market.json, we use that instead. + flag.Parse() + + marketMap := mmtypes.MarketMap{ + Markets: make(map[string]mmtypes.Market), + } + + if *useCore { + fmt.Fprintf(flag.CommandLine.Output(), "Using core markets\n") + marketMap = mergeMarketMaps(marketMap, constants.CoreMarketMap) + } + + if *useRaydium { + fmt.Fprintf(flag.CommandLine.Output(), "Using raydium markets\n") + marketMap = mergeMarketMaps(marketMap, constants.RaydiumMarketMap) + } + + if *useUniswapV3Base { + fmt.Fprintf(flag.CommandLine.Output(), "Using uniswapv3 base markets\n") + marketMap = mergeMarketMaps(marketMap, constants.UniswapV3BaseMarketMap) + } + + if *useCoinGecko { + fmt.Fprintf(flag.CommandLine.Output(), "Using coingecko markets\n") + marketMap = mergeMarketMaps(marketMap, constants.CoinGeckoMarketMap) + } + + if err := marketMap.ValidateBasic(); err != nil { + fmt.Fprintf(flag.CommandLine.Output(), "failed to validate market map: %s\n", err) + panic(err) + } + + // Write the market map to the temporary file. + if *tempFile == "" { + fmt.Fprintf(flag.CommandLine.Output(), "temp file cannot be empty\n") + panic("temp file cannot be empty") + } + + if err := mmtypes.WriteMarketMapToFile(marketMap, *tempFile); err != nil { + fmt.Fprintf(flag.CommandLine.Output(), "failed to write market map to file: %s\n", err) + panic(err) + } +} + +// mergeMarketMaps merges the two market maps together. If a market already exists in one of the maps, we +// merge based on the provider set. +func mergeMarketMaps(this, other mmtypes.MarketMap) mmtypes.MarketMap { + for name, otherMarket := range other.Markets { + // If the market does not exist in this map, we add it. + thisMarket, ok := this.Markets[name] + if !ok { + this.Markets[name] = otherMarket + continue + } + + seen := make(map[string]struct{}) + for _, provider := range thisMarket.ProviderConfigs { + key := providerConfigToKey(provider) + seen[key] = struct{}{} + } + + for _, provider := range otherMarket.ProviderConfigs { + key := providerConfigToKey(provider) + if _, ok := seen[key]; !ok { + thisMarket.ProviderConfigs = append(thisMarket.ProviderConfigs, provider) + } + } + + this.Markets[name] = thisMarket + } + + return this +} + +func providerConfigToKey(cfg mmtypes.ProviderConfig) string { + return cfg.Name + cfg.OffChainTicker +}