fix: 修复 RPC 错误时误创建自动卖出记录的问题
- 当链上查询市场条件出现 RPC 错误(execution reverted)时,不再降级到其他数据源 - 抛出异常让调用方决定如何处理,避免在市场不存在或尚未创建时误判为已卖出 - 修改 getPriceFromChainCondition 返回 Pair<BigDecimal?, Boolean>,第二个值表示是否发生 RPC 错误 - 在 getCurrentMarketPrice 中检测到 RPC 错误时抛出异常,PositionCheckService 会捕获并跳过该市场的处理
This commit is contained in:
+31
-10
@@ -43,12 +43,20 @@ class MarketPriceService(
|
|||||||
*/
|
*/
|
||||||
suspend fun getCurrentMarketPrice(marketId: String, outcomeIndex: Int): BigDecimal {
|
suspend fun getCurrentMarketPrice(marketId: String, outcomeIndex: Int): BigDecimal {
|
||||||
// 1. 优先从链上查询市场结算结果
|
// 1. 优先从链上查询市场结算结果
|
||||||
val chainPrice = getPriceFromChainCondition(marketId, outcomeIndex)
|
val (chainPrice, hasRpcError) = getPriceFromChainCondition(marketId, outcomeIndex)
|
||||||
if (chainPrice != null) {
|
if (chainPrice != null) {
|
||||||
// 截位到 4 位小数(向下截断,不四舍五入)
|
// 截位到 4 位小数(向下截断,不四舍五入)
|
||||||
return chainPrice.setScale(4, java.math.RoundingMode.DOWN)
|
return chainPrice.setScale(4, java.math.RoundingMode.DOWN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果链上查询出现 RPC 错误(execution reverted),说明市场可能不存在或尚未创建
|
||||||
|
// 在这种情况下,不应该继续处理,应该抛出异常,让调用方决定如何处理
|
||||||
|
if (hasRpcError) {
|
||||||
|
val errorMsg = "链上查询市场条件出现 RPC 错误(execution reverted),市场可能不存在或尚未创建: marketId=$marketId, outcomeIndex=$outcomeIndex"
|
||||||
|
logger.warn(errorMsg)
|
||||||
|
throw IllegalStateException(errorMsg)
|
||||||
|
}
|
||||||
|
|
||||||
// 2. 从 CLOB API 查询订单簿价格(最准确,优先使用)
|
// 2. 从 CLOB API 查询订单簿价格(最准确,优先使用)
|
||||||
val orderbookPrice = getPriceFromClobOrderbook(marketId, outcomeIndex)
|
val orderbookPrice = getPriceFromClobOrderbook(marketId, outcomeIndex)
|
||||||
if (orderbookPrice != null) {
|
if (orderbookPrice != null) {
|
||||||
@@ -75,8 +83,10 @@ class MarketPriceService(
|
|||||||
* - payout > 0(赢了)→ 返回 1.0
|
* - payout > 0(赢了)→ 返回 1.0
|
||||||
* - payout == 0(输了)→ 返回 0.0
|
* - payout == 0(输了)→ 返回 0.0
|
||||||
* 如果市场未结算或查询失败,返回 null
|
* 如果市场未结算或查询失败,返回 null
|
||||||
|
*
|
||||||
|
* @return Pair<BigDecimal?, Boolean> 第一个值是价格(如果已结算),第二个值表示是否发生了 RPC 错误(execution reverted)
|
||||||
*/
|
*/
|
||||||
private suspend fun getPriceFromChainCondition(marketId: String, outcomeIndex: Int): BigDecimal? {
|
private suspend fun getPriceFromChainCondition(marketId: String, outcomeIndex: Int): Pair<BigDecimal?, Boolean> {
|
||||||
return try {
|
return try {
|
||||||
val chainResult = blockchainService.getCondition(marketId)
|
val chainResult = blockchainService.getCondition(marketId)
|
||||||
chainResult.fold(
|
chainResult.fold(
|
||||||
@@ -87,30 +97,41 @@ class MarketPriceService(
|
|||||||
when {
|
when {
|
||||||
payout > BigInteger.ZERO -> {
|
payout > BigInteger.ZERO -> {
|
||||||
logger.info("从链上查询到市场已结算,该 outcome 赢了: marketId=$marketId, outcomeIndex=$outcomeIndex, payout=$payout")
|
logger.info("从链上查询到市场已结算,该 outcome 赢了: marketId=$marketId, outcomeIndex=$outcomeIndex, payout=$payout")
|
||||||
return BigDecimal.ONE
|
return Pair(BigDecimal.ONE, false)
|
||||||
}
|
}
|
||||||
payout == BigInteger.ZERO -> {
|
payout == BigInteger.ZERO -> {
|
||||||
logger.info("从链上查询到市场已结算,该 outcome 输了: marketId=$marketId, outcomeIndex=$outcomeIndex, payout=$payout")
|
logger.info("从链上查询到市场已结算,该 outcome 输了: marketId=$marketId, outcomeIndex=$outcomeIndex, payout=$payout")
|
||||||
return BigDecimal.ZERO
|
return Pair(BigDecimal.ZERO, false)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
logger.warn("从链上查询到异常的 payout 值: marketId=$marketId, outcomeIndex=$outcomeIndex, payout=$payout")
|
logger.warn("从链上查询到异常的 payout 值: marketId=$marketId, outcomeIndex=$outcomeIndex, payout=$payout")
|
||||||
null
|
Pair(null, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.debug("从链上查询到市场尚未结算: marketId=$marketId, payouts=${payouts.size}")
|
logger.debug("从链上查询到市场尚未结算: marketId=$marketId, payouts=${payouts.size}")
|
||||||
null
|
Pair(null, false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onFailure = { e ->
|
onFailure = { e ->
|
||||||
logger.debug("链上查询市场条件失败,降级到 API 查询: marketId=$marketId, error=${e.message}")
|
// 检查是否是 execution reverted 错误
|
||||||
null
|
val isRpcError = e.message?.contains("execution reverted", ignoreCase = true) == true
|
||||||
|
if (isRpcError) {
|
||||||
|
logger.warn("链上查询市场条件出现 RPC 错误(execution reverted),可能市场不存在或尚未创建: marketId=$marketId, error=${e.message}")
|
||||||
|
} else {
|
||||||
|
logger.debug("链上查询市场条件失败,降级到 API 查询: marketId=$marketId, error=${e.message}")
|
||||||
|
}
|
||||||
|
Pair(null, isRpcError)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logger.debug("链上查询市场条件异常: marketId=$marketId, outcomeIndex=$outcomeIndex, error=${e.message}")
|
val isRpcError = e.message?.contains("execution reverted", ignoreCase = true) == true
|
||||||
null
|
if (isRpcError) {
|
||||||
|
logger.warn("链上查询市场条件异常(execution reverted): marketId=$marketId, outcomeIndex=$outcomeIndex, error=${e.message}")
|
||||||
|
} else {
|
||||||
|
logger.debug("链上查询市场条件异常: marketId=$marketId, outcomeIndex=$outcomeIndex, error=${e.message}")
|
||||||
|
}
|
||||||
|
Pair(null, isRpcError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user