Refact multicall

This commit is contained in:
2024-08-17 07:57:14 +07:00
parent 7bb6a3638e
commit acaf3f7346
4 changed files with 176 additions and 160 deletions

View File

@@ -181,147 +181,164 @@ public class GmxV2Service
}
public async Task<List<GmxMarketInfo>> GetMarketInfosAsync(Web3 web3)
{
var markets = await GetMarketsAsync(web3);
var readerResult = new List<GmxMarketInfo>();
var readerCalls = new List<Call>();
var datastoreCalls = new List<Call>();
markets = markets.Where(m => !m.IsSpotOnly).ToList();
foreach (var market in markets)
{
var markets = await GetMarketsAsync(web3);
var readerResult = new List<GmxMarketInfo>();
foreach (var market in markets)
var tokensData = await GetTokensData(web3);
var marketPrices = GmxHelpers.GetContractMarketPrices(tokensData, market);
var marketProps = new MarketsProps()
{
var tokensData = await GetTokensData(web3);
var marketPrices = GmxHelpers.GetContractMarketPrices(tokensData, market);
var marketProps = new MarketsProps()
{
MarketToken = market.MarketToken,
IndexToken = market.IndexToken,
LongToken = market.LongToken,
ShortToken = market.ShortToken
};
var getMarketInfoCallData = new GetMarketInfoFunction
{
DataStore = Arbitrum.AddressV2.DataStore,
Prices = marketPrices,
MarketKey = market.MarketToken
}.GetCallData();
var getMarketInfoCall = new Call
{
Target = Arbitrum.AddressV2.Reader,
CallData = getMarketInfoCallData
};
var getMarketTokenPriceCallData = new GetMarketTokenPriceFunction
{
DataStore = Arbitrum.AddressV2.DataStore,
Market = marketProps,
IndexTokenPrice = marketPrices.IndexTokenPrice,
LongTokenPrice = marketPrices.LongTokenPrice,
ShortTokenPrice = marketPrices.ShortTokenPrice,
PnlFactorType = _helpers.HashString(Constants.GMX.MAX_PNL_FACTOR_FOR_TRADERS),
Maximize = true
}.GetCallData();
var getMarketTokenPriceCall = new Call
{
Target = Arbitrum.AddressV2.Reader,
CallData = getMarketTokenPriceCallData
};
var getMarketTokenPriceMinCallData = new GetMarketTokenPriceFunction
{
DataStore = Arbitrum.AddressV2.DataStore,
Market = marketProps,
IndexTokenPrice = marketPrices.IndexTokenPrice,
LongTokenPrice = marketPrices.LongTokenPrice,
ShortTokenPrice = marketPrices.ShortTokenPrice,
PnlFactorType = _helpers.HashString(Constants.GMX.MAX_PNL_FACTOR_FOR_TRADERS),
Maximize = false
}.GetCallData();
var getMarketTokenPriceMinCall = new Call
{
Target = Arbitrum.AddressV2.Reader,
CallData = getMarketTokenPriceMinCallData
};
MarketToken = market.MarketToken,
IndexToken = market.IndexToken,
LongToken = market.LongToken,
ShortToken = market.ShortToken
};
var readerMulticall = new AggregateFunction();
readerMulticall.Calls = new List<Call>();
readerMulticall.Calls.Add(getMarketInfoCall);
readerMulticall.Calls.Add(getMarketTokenPriceCall);
readerMulticall.Calls.Add(getMarketTokenPriceMinCall);
var getMarketInfoCallData = new GetMarketInfoFunction
{
DataStore = Arbitrum.AddressV2.DataStore,
Prices = marketPrices,
MarketKey = market.MarketToken
}.GetCallData();
var getMarketInfoCall = new Call
{
Target = Arbitrum.AddressV2.Reader,
CallData = getMarketInfoCallData
};
var queryHandler = web3.Eth.GetContractQueryHandler<AggregateFunction>();
var readerCallResults = await queryHandler
.QueryDeserializingToObjectAsync<AggregateOutputDTO>(readerMulticall, Arbitrum.AddressV2.Multicall)
.ConfigureAwait(false);
var getMarketTokenPriceCallData = new GetMarketTokenPriceFunction
{
DataStore = Arbitrum.AddressV2.DataStore,
Market = marketProps,
IndexTokenPrice = marketPrices.IndexTokenPrice,
LongTokenPrice = marketPrices.LongTokenPrice,
ShortTokenPrice = marketPrices.ShortTokenPrice,
PnlFactorType = _helpers.HashString(Constants.GMX.MAX_PNL_FACTOR_FOR_TRADERS),
Maximize = true
}.GetCallData();
var getMarketTokenPriceCall = new Call
{
Target = Arbitrum.AddressV2.Reader,
CallData = getMarketTokenPriceCallData
};
var marketInfo = new GetMarketInfoOutputDTO().DecodeOutput(readerCallResults.ReturnData[0].ToHex());
var marketTokenPriceMax =
new GetMarketTokenPriceOutputDTO().DecodeOutput(readerCallResults.ReturnData[1].ToHex());
var marketTokenPriceMin =
new GetMarketTokenPriceOutputDTO().DecodeOutput(readerCallResults.ReturnData[2].ToHex());
var getMarketTokenPriceMinCallData = new GetMarketTokenPriceFunction
{
DataStore = Arbitrum.AddressV2.DataStore,
Market = marketProps,
IndexTokenPrice = marketPrices.IndexTokenPrice,
LongTokenPrice = marketPrices.LongTokenPrice,
ShortTokenPrice = marketPrices.ShortTokenPrice,
PnlFactorType = _helpers.HashString(Constants.GMX.MAX_PNL_FACTOR_FOR_TRADERS),
Maximize = false
}.GetCallData();
var getMarketTokenPriceMinCall = new Call
{
Target = Arbitrum.AddressV2.Reader,
CallData = getMarketTokenPriceMinCallData
};
// Get hashed key to call datastore
var marketKeys = GmxKeysService.GetMarketKeys(market.MarketToken);
if (marketKeys == null)
continue;
readerCalls.Add(getMarketInfoCall);
readerCalls.Add(getMarketTokenPriceCall);
readerCalls.Add(getMarketTokenPriceMinCall);
var longInterestUsingLongTokenCallData = new GetUintFunction()
{
Key = marketKeys.LongInterestUsingLongToken.HexToByteArray()
}.GetCallData();
var longInterestUsingLongTokenCall = new Call
{
Target = Arbitrum.AddressV2.DataStore,
CallData = longInterestUsingLongTokenCallData
};
var longInterestUsingShortTokenCallData = new GetUintFunction()
{
Key = marketKeys.LongInterestUsingShortToken.HexToByteArray()
}.GetCallData();
var longInterestUsingShortTokenCall = new Call
{
Target = Arbitrum.AddressV2.DataStore,
CallData = longInterestUsingShortTokenCallData
};
var shortInterestUsingLongTokenCallData = new GetUintFunction()
{
Key = marketKeys.ShortInterestUsingLongToken.HexToByteArray()
}.GetCallData();
var shortInterestUsingLongTokenCall = new Call
{
Target = Arbitrum.AddressV2.DataStore,
CallData = shortInterestUsingLongTokenCallData
};
var shortInterestUsingShortTokenCallData = new GetUintFunction()
{
Key = marketKeys.ShortInterestUsingShortToken.HexToByteArray()
}.GetCallData();
var shortInterestUsingShortTokenCall = new Call
{
Target = Arbitrum.AddressV2.DataStore,
CallData = shortInterestUsingShortTokenCallData
};
var marketKeys = GmxKeysService.GetMarketKeys(market.MarketToken);
if (marketKeys == null)
continue;
var dataStoreMulticall = new AggregateFunction();
dataStoreMulticall.Calls = new List<Call>();
dataStoreMulticall.Calls.Add(longInterestUsingLongTokenCall);
dataStoreMulticall.Calls.Add(longInterestUsingShortTokenCall);
dataStoreMulticall.Calls.Add(shortInterestUsingLongTokenCall);
dataStoreMulticall.Calls.Add(shortInterestUsingShortTokenCall);
var longInterestUsingLongTokenCallData = new GetUintFunction
{
Key = marketKeys.LongInterestUsingLongToken.HexToByteArray()
}.GetCallData();
var longInterestUsingLongTokenCall = new Call
{
Target = Arbitrum.AddressV2.DataStore,
CallData = longInterestUsingLongTokenCallData
};
var longInterestUsingShortTokenCallData = new GetUintFunction
{
Key = marketKeys.LongInterestUsingShortToken.HexToByteArray()
}.GetCallData();
var longInterestUsingShortTokenCall = new Call
{
Target = Arbitrum.AddressV2.DataStore,
CallData = longInterestUsingShortTokenCallData
};
var shortInterestUsingLongTokenCallData = new GetUintFunction
{
Key = marketKeys.ShortInterestUsingLongToken.HexToByteArray()
}.GetCallData();
var shortInterestUsingLongTokenCall = new Call
{
Target = Arbitrum.AddressV2.DataStore,
CallData = shortInterestUsingLongTokenCallData
};
var shortInterestUsingShortTokenCallData = new GetUintFunction
{
Key = marketKeys.ShortInterestUsingShortToken.HexToByteArray()
}.GetCallData();
var shortInterestUsingShortTokenCall = new Call
{
Target = Arbitrum.AddressV2.DataStore,
CallData = shortInterestUsingShortTokenCallData
};
// Call datastore to get market info
var dataStoreQueryHandler = web3.Eth.GetContractQueryHandler<AggregateFunction>();
var dataStoreCallResults = await dataStoreQueryHandler
.QueryDeserializingToObjectAsync<AggregateOutputDTO>(dataStoreMulticall, Arbitrum.AddressV2.Multicall)
.ConfigureAwait(false);
var marketInfos = GmxMappers.Map(marketInfo.ReturnValue1);
readerResult.Add(new GmxMarketInfo()
{
Market = marketInfos,
Infos = DecodeFundingRateOutput(dataStoreCallResults, marketInfos.IsSameCollaterals),
MarketTokenPriceMax = GmxMappers.Map(marketTokenPriceMax),
MarketTokenPriceMin = GmxMappers.Map(marketTokenPriceMin)
});
}
return readerResult;
datastoreCalls.Add(longInterestUsingLongTokenCall);
datastoreCalls.Add(longInterestUsingShortTokenCall);
datastoreCalls.Add(shortInterestUsingLongTokenCall);
datastoreCalls.Add(shortInterestUsingShortTokenCall);
}
var readerMulticall = new AggregateFunction { Calls = readerCalls };
var datastoreMulticall = new AggregateFunction { Calls = datastoreCalls };
var queryHandler = web3.Eth.GetContractQueryHandler<AggregateFunction>();
var readerCallResults = await queryHandler
.QueryDeserializingToObjectAsync<AggregateOutputDTO>(readerMulticall, Arbitrum.AddressV2.Multicall)
.ConfigureAwait(false);
var datastoreCallResults = await queryHandler
.QueryDeserializingToObjectAsync<AggregateOutputDTO>(datastoreMulticall, Arbitrum.AddressV2.Multicall)
.ConfigureAwait(false);
int readerCallIndex = 0;
int datastoreCallIndex = 0;
foreach (var market in markets)
{
var marketInfo = new GetMarketInfoOutputDTO().DecodeOutput(readerCallResults.ReturnData[readerCallIndex++].ToHex());
var marketTokenPriceMax = new GetMarketTokenPriceOutputDTO().DecodeOutput(readerCallResults.ReturnData[readerCallIndex++].ToHex());
var marketTokenPriceMin = new GetMarketTokenPriceOutputDTO().DecodeOutput(readerCallResults.ReturnData[readerCallIndex++].ToHex());
var marketKeys = GmxKeysService.GetMarketKeys(market.MarketToken);
if (marketKeys == null)
continue;
var longInterestUsingLongToken = new GetUintOutputDTO().DecodeOutput(datastoreCallResults.ReturnData[datastoreCallIndex++].ToHex()).ReturnValue1;
var longInterestUsingShortToken = new GetUintOutputDTO().DecodeOutput(datastoreCallResults.ReturnData[datastoreCallIndex++].ToHex()).ReturnValue1;
var shortInterestUsingLongToken = new GetUintOutputDTO().DecodeOutput(datastoreCallResults.ReturnData[datastoreCallIndex++].ToHex()).ReturnValue1;
var shortInterestUsingShortToken = new GetUintOutputDTO().DecodeOutput(datastoreCallResults.ReturnData[datastoreCallIndex++].ToHex()).ReturnValue1;
var marketInfos = GmxMappers.Map(marketInfo.ReturnValue1);
readerResult.Add(new GmxMarketInfo
{
Market = marketInfos,
Infos = new GmxMarketInfos
{
LongInterestUsd = longInterestUsingLongToken + longInterestUsingShortToken,
ShortInterestUsd = shortInterestUsingLongToken + shortInterestUsingShortToken
},
MarketTokenPriceMax = GmxMappers.Map(marketTokenPriceMax),
MarketTokenPriceMin = GmxMappers.Map(marketTokenPriceMin)
});
}
return readerResult;
}
private GmxMarketInfos DecodeFundingRateOutput(AggregateOutputDTO results, bool isSameCollaterals)
{
var marketDivisor = new BigInteger(isSameCollaterals ? 2 : 1);