fix(android): 分批查询交易记录以绕过 RPC 10000 区块限制
RPC 节点限制每次查询最多 10000 个区块,修改为分批查询: - 每批查询 10000 个区块 - 总共扫描最近 100000 个区块(约 10 批) - 添加批次日志输出 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
6e03c1c798
commit
78e105d46d
|
|
@ -3179,16 +3179,18 @@ data class ParticipantStatusInfo(
|
||||||
val currentBlockHex = getCurrentBlockNumber(client, rpcUrl)
|
val currentBlockHex = getCurrentBlockNumber(client, rpcUrl)
|
||||||
val currentBlock = currentBlockHex?.removePrefix("0x")?.toLongOrNull(16) ?: 0L
|
val currentBlock = currentBlockHex?.removePrefix("0x")?.toLongOrNull(16) ?: 0L
|
||||||
|
|
||||||
// 查询最近 200000 个区块的历史(Kava 出块快,确保覆盖足够长的时间)
|
// RPC 节点限制:每次最多查询 10000 个区块
|
||||||
val scanBlockCount = 200000L
|
// 分批查询最近 100000 个区块
|
||||||
val fromBlock = if (currentBlock > scanBlockCount) {
|
val maxBlocksPerRequest = 10000L
|
||||||
"0x${(currentBlock - scanBlockCount).toString(16)}"
|
val totalBlocksToScan = 100000L
|
||||||
|
val startBlock = if (currentBlock > totalBlocksToScan) {
|
||||||
|
currentBlock - totalBlocksToScan
|
||||||
} else {
|
} else {
|
||||||
"0x0"
|
0L
|
||||||
}
|
}
|
||||||
|
|
||||||
android.util.Log.d("TssRepository", "[SYNC-ERC20] Current block: $currentBlock ($currentBlockHex)")
|
android.util.Log.d("TssRepository", "[SYNC-ERC20] Current block: $currentBlock")
|
||||||
android.util.Log.d("TssRepository", "[SYNC-ERC20] Scanning from block $fromBlock to latest (${scanBlockCount} blocks)")
|
android.util.Log.d("TssRepository", "[SYNC-ERC20] Scanning blocks $startBlock to $currentBlock (total: ${currentBlock - startBlock})")
|
||||||
|
|
||||||
// Transfer event signature: keccak256("Transfer(address,address,uint256)")
|
// Transfer event signature: keccak256("Transfer(address,address,uint256)")
|
||||||
val transferTopic = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
|
val transferTopic = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
|
||||||
|
|
@ -3198,65 +3200,76 @@ data class ParticipantStatusInfo(
|
||||||
|
|
||||||
var totalSynced = 0
|
var totalSynced = 0
|
||||||
|
|
||||||
// 查询发送的交易 (from = address)
|
// 分批查询,每批 10000 个区块
|
||||||
val sentRequest = """
|
var fromBlock = startBlock
|
||||||
{
|
var batchCount = 0
|
||||||
"jsonrpc": "2.0",
|
while (fromBlock < currentBlock) {
|
||||||
"method": "eth_getLogs",
|
val toBlock = minOf(fromBlock + maxBlocksPerRequest - 1, currentBlock)
|
||||||
"params": [{
|
batchCount++
|
||||||
"address": "$contractAddress",
|
|
||||||
"topics": ["$transferTopic", "$paddedAddress", null],
|
val fromBlockHex = "0x${fromBlock.toString(16)}"
|
||||||
"fromBlock": "$fromBlock",
|
val toBlockHex = "0x${toBlock.toString(16)}"
|
||||||
"toBlock": "latest"
|
|
||||||
}],
|
android.util.Log.d("TssRepository", "[SYNC-ERC20] Batch #$batchCount: blocks $fromBlock-$toBlock")
|
||||||
"id": 1
|
|
||||||
|
// 查询发送的交易 (from = address)
|
||||||
|
val sentRequest = """
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": "eth_getLogs",
|
||||||
|
"params": [{
|
||||||
|
"address": "$contractAddress",
|
||||||
|
"topics": ["$transferTopic", "$paddedAddress", null],
|
||||||
|
"fromBlock": "$fromBlockHex",
|
||||||
|
"toBlock": "$toBlockHex"
|
||||||
|
}],
|
||||||
|
"id": 1
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
val sentResponse = client.newCall(
|
||||||
|
okhttp3.Request.Builder()
|
||||||
|
.url(rpcUrl)
|
||||||
|
.post(sentRequest.toRequestBody(jsonMediaType))
|
||||||
|
.build()
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
val sentBody = sentResponse.body?.string()
|
||||||
|
if (sentBody != null) {
|
||||||
|
totalSynced += parseAndSaveTransferLogs(sentBody, shareId, address, tokenType, "SENT")
|
||||||
}
|
}
|
||||||
""".trimIndent()
|
|
||||||
|
|
||||||
val sentResponse = client.newCall(
|
// 查询接收的交易 (to = address)
|
||||||
okhttp3.Request.Builder()
|
val receivedRequest = """
|
||||||
.url(rpcUrl)
|
{
|
||||||
.post(sentRequest.toRequestBody(jsonMediaType))
|
"jsonrpc": "2.0",
|
||||||
.build()
|
"method": "eth_getLogs",
|
||||||
).execute()
|
"params": [{
|
||||||
|
"address": "$contractAddress",
|
||||||
|
"topics": ["$transferTopic", null, "$paddedAddress"],
|
||||||
|
"fromBlock": "$fromBlockHex",
|
||||||
|
"toBlock": "$toBlockHex"
|
||||||
|
}],
|
||||||
|
"id": 2
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
val sentBody = sentResponse.body?.string()
|
val receivedResponse = client.newCall(
|
||||||
android.util.Log.d("TssRepository", "[SYNC-ERC20] SENT response code: ${sentResponse.code}")
|
okhttp3.Request.Builder()
|
||||||
if (sentBody != null) {
|
.url(rpcUrl)
|
||||||
android.util.Log.d("TssRepository", "[SYNC-ERC20] SENT response preview: ${sentBody.take(500)}")
|
.post(receivedRequest.toRequestBody(jsonMediaType))
|
||||||
totalSynced += parseAndSaveTransferLogs(sentBody, shareId, address, tokenType, "SENT")
|
.build()
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
val receivedBody = receivedResponse.body?.string()
|
||||||
|
if (receivedBody != null) {
|
||||||
|
totalSynced += parseAndSaveTransferLogs(receivedBody, shareId, address, tokenType, "RECEIVED")
|
||||||
|
}
|
||||||
|
|
||||||
|
fromBlock = toBlock + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询接收的交易 (to = address)
|
android.util.Log.d("TssRepository", "[SYNC-ERC20] Completed $batchCount batches, synced $totalSynced ${tokenType.name} transactions")
|
||||||
val receivedRequest = """
|
|
||||||
{
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"method": "eth_getLogs",
|
|
||||||
"params": [{
|
|
||||||
"address": "$contractAddress",
|
|
||||||
"topics": ["$transferTopic", null, "$paddedAddress"],
|
|
||||||
"fromBlock": "$fromBlock",
|
|
||||||
"toBlock": "latest"
|
|
||||||
}],
|
|
||||||
"id": 2
|
|
||||||
}
|
|
||||||
""".trimIndent()
|
|
||||||
|
|
||||||
val receivedResponse = client.newCall(
|
|
||||||
okhttp3.Request.Builder()
|
|
||||||
.url(rpcUrl)
|
|
||||||
.post(receivedRequest.toRequestBody(jsonMediaType))
|
|
||||||
.build()
|
|
||||||
).execute()
|
|
||||||
|
|
||||||
val receivedBody = receivedResponse.body?.string()
|
|
||||||
android.util.Log.d("TssRepository", "[SYNC-ERC20] RECEIVED response code: ${receivedResponse.code}")
|
|
||||||
if (receivedBody != null) {
|
|
||||||
android.util.Log.d("TssRepository", "[SYNC-ERC20] RECEIVED response preview: ${receivedBody.take(500)}")
|
|
||||||
totalSynced += parseAndSaveTransferLogs(receivedBody, shareId, address, tokenType, "RECEIVED")
|
|
||||||
}
|
|
||||||
|
|
||||||
android.util.Log.d("TssRepository", "[SYNC-ERC20] Synced $totalSynced ${tokenType.name} transactions")
|
|
||||||
Result.success(totalSynced)
|
Result.success(totalSynced)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
android.util.Log.e("TssRepository", "[SYNC-ERC20] Error: ${e.message}", e)
|
android.util.Log.e("TssRepository", "[SYNC-ERC20] Error: ${e.message}", e)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue