redpacket eth indexer poll error

This commit is contained in:
hawklin2017 2026-05-15 10:59:03 +08:00
parent ef779eeedb
commit 2bc600f353
5 changed files with 64 additions and 19 deletions

View File

@ -29,3 +29,5 @@ tron:
# Indexer polling interval (in seconds). Used by both EVM and TRON event indexers. # Indexer polling interval (in seconds). Used by both EVM and TRON event indexers.
indexer: indexer:
pollInterval: 5 pollInterval: 5
# EVM only: max block span per eth_getLogs request (0 = default 2000). Increase if your node allows larger ranges.
maxBlocksPerPoll: 2000

View File

@ -14,25 +14,48 @@ import (
"github.com/openimsdk/tools/log" "github.com/openimsdk/tools/log"
) )
const defaultIndexerMaxBlocksPerPoll uint64 = 2000
type Indexer struct { type Indexer struct {
client *ChainClient client *ChainClient
db controller.RedPacketDatabase db controller.RedPacketDatabase
pollInterval time.Duration pollInterval time.Duration
lastBlock uint64 lastBlock uint64
contractAddr common.Address contractAddr common.Address
maxBlocksPerPoll uint64 // 0 => defaultIndexerMaxBlocksPerPoll
} }
func NewIndexer(client *ChainClient, db controller.RedPacketDatabase, pollInterval int, startBlock uint64) *Indexer { func NewIndexer(client *ChainClient, db controller.RedPacketDatabase, pollInterval int, startBlock uint64, maxBlocksPerPoll int) *Indexer {
if pollInterval <= 0 { if pollInterval <= 0 {
pollInterval = 5 pollInterval = 5
} }
return &Indexer{ var maxB uint64
client: client, if maxBlocksPerPoll > 0 {
db: db, maxB = uint64(maxBlocksPerPoll)
pollInterval: time.Duration(pollInterval) * time.Second,
lastBlock: startBlock,
contractAddr: client.contractAddr,
} }
return &Indexer{
client: client,
db: db,
pollInterval: time.Duration(pollInterval) * time.Second,
lastBlock: startBlock,
contractAddr: client.contractAddr,
maxBlocksPerPoll: maxB,
}
}
func (i *Indexer) chunkEndBlock(chainTip uint64) uint64 {
maxSpan := i.maxBlocksPerPoll
if maxSpan == 0 {
maxSpan = defaultIndexerMaxBlocksPerPoll
}
if chainTip <= i.lastBlock {
return i.lastBlock
}
span := chainTip - i.lastBlock
if span > maxSpan {
return i.lastBlock + maxSpan
}
return chainTip
} }
func (i *Indexer) Start(ctx context.Context) { func (i *Indexer) Start(ctx context.Context) {
@ -105,20 +128,25 @@ func (i *Indexer) poll(ctx context.Context) error {
return fmt.Errorf("get header failed: %w", err) return fmt.Errorf("get header failed: %w", err)
} }
currentBlock := header.Number.Uint64() chainTip := header.Number.Uint64()
if currentBlock <= i.lastBlock { if chainTip <= i.lastBlock {
return nil
}
toBlock := i.chunkEndBlock(chainTip)
if toBlock <= i.lastBlock {
return nil return nil
} }
query := ethereum.FilterQuery{ query := ethereum.FilterQuery{
FromBlock: big.NewInt(int64(i.lastBlock + 1)), FromBlock: big.NewInt(int64(i.lastBlock + 1)),
ToBlock: big.NewInt(int64(currentBlock)), ToBlock: big.NewInt(int64(toBlock)),
Addresses: []common.Address{i.contractAddr}, Addresses: []common.Address{i.contractAddr},
} }
logs, err := i.client.client.FilterLogs(ctx, query) logs, err := i.client.client.FilterLogs(ctx, query)
if err != nil { if err != nil {
return fmt.Errorf("filter logs failed: %w", err) return fmt.Errorf("filter logs failed (blocks %d-%d): %w", i.lastBlock+1, toBlock, err)
} }
logPtrs := make([]*types.Log, len(logs)) logPtrs := make([]*types.Log, len(logs))
@ -137,8 +165,12 @@ func (i *Indexer) poll(ctx context.Context) error {
} }
} }
i.lastBlock = currentBlock i.lastBlock = toBlock
log.ZInfo(ctx, "redpacket eth indexed", "block", currentBlock, "events", len(events)) if toBlock < chainTip {
log.ZDebug(ctx, "redpacket eth indexer chunk done, catching up", "indexedTo", toBlock, "chainTip", chainTip, "events", len(events))
} else {
log.ZInfo(ctx, "redpacket eth indexed", "block", toBlock, "events", len(events))
}
return nil return nil
} }

View File

@ -138,7 +138,7 @@ func Start(ctx context.Context, conf *Config, registry discovery.SvcDiscoveryReg
pbredpacket.RegisterRedPacketServer(server, srv) pbredpacket.RegisterRedPacketServer(server, srv)
if chainClient != nil { if chainClient != nil {
ethIndexer := chain.NewIndexer(chainClient, repo, conf.RpcConfig.Indexer.PollInterval, 0) ethIndexer := chain.NewIndexer(chainClient, repo, conf.RpcConfig.Indexer.PollInterval, 0, conf.RpcConfig.Indexer.MaxBlocksPerPoll)
ethIndexer.Start(ctx) ethIndexer.Start(ctx)
} }
if tronClient != nil { if tronClient != nil {

View File

@ -97,6 +97,10 @@ func (s *rtcServer) handleInvite(ctx context.Context, req *rtc.SignalInviteReq,
inv.InviterUserID = req.UserID inv.InviterUserID = req.UserID
inv.InitiateTime = time.Now().UnixMilli() inv.InitiateTime = time.Now().UnixMilli()
if len(inv.InviteeUserIDList) == 0 {
return nil, errs.ErrArgs.WrapMsg("no invitees", "inviteeUserIDList", inv.InviteeUserIDList)
}
for _, inviteeID := range inv.InviteeUserIDList { for _, inviteeID := range inv.InviteeUserIDList {
allowed, err := s.isCallAllowed(ctx, req.UserID, inviteeID) allowed, err := s.isCallAllowed(ctx, req.UserID, inviteeID)
if err != nil { if err != nil {
@ -119,6 +123,10 @@ func (s *rtcServer) handleInvite(ctx context.Context, req *rtc.SignalInviteReq,
} }
inv.BusyLineUserIDList = busyUserIDs inv.BusyLineUserIDList = busyUserIDs
if len(inv.InviteeUserIDList) == len(busyUserIDs) {
return nil, errs.ErrNoPermission.WrapMsg("all invitees are busy", "inviteeUserIDList", inv.InviteeUserIDList)
}
// 从主叫用户资料获取铃声 URL注入到邀请信息中被叫方收到后播放主叫方铃声 // 从主叫用户资料获取铃声 URL注入到邀请信息中被叫方收到后播放主叫方铃声
if inviterInfo, err := s.userClient.GetUserInfo(ctx, req.UserID); err == nil && inviterInfo.CallRingtoneURL != "" { if inviterInfo, err := s.userClient.GetUserInfo(ctx, req.UserID); err == nil && inviterInfo.CallRingtoneURL != "" {
inv.CallerRingtoneURL = inviterInfo.CallRingtoneURL inv.CallerRingtoneURL = inviterInfo.CallRingtoneURL

View File

@ -532,6 +532,9 @@ type RedPacketTron struct {
type RedPacketIndexer struct { type RedPacketIndexer struct {
PollInterval int `mapstructure:"pollInterval"` PollInterval int `mapstructure:"pollInterval"`
// MaxBlocksPerPoll limits each eth_getLogs range (lastBlock+1 .. toBlock). Many public RPCs
// reject large ranges; 0 means use default 2000.
MaxBlocksPerPoll int `mapstructure:"maxBlocksPerPoll"`
} }
// FullConfig stores all configurations for before and after events // FullConfig stores all configurations for before and after events