feat(v2): crypto 预留表冷启动兜底——注入 loader 从 pending attempts 重建 reservation(兜重启丢内存)
This commit is contained in:
@@ -206,3 +206,35 @@ func TestReservationKeyByAddress(t *testing.T) {
|
||||
t.Fatalf("共享地址的两个账户不应分配相同金额: %d", amt1)
|
||||
}
|
||||
}
|
||||
|
||||
// 冷启动兜底:装配期注入的 ReservationLoader 在 Warm 时把仍在冷却窗内的 pending
|
||||
// 预留灌回内存表;超冷却窗的旧预留(迟到旧款已不可能匹配)不必恢复。
|
||||
func TestWarmRebuildsReservationsFromLoader(t *testing.T) {
|
||||
const addr = "TWarmTestAddr000000000000000000000"
|
||||
t.Setenv("CRY_ADDRESS", addr)
|
||||
reg := accounts.New([]config.AccountConfig{
|
||||
{AccountID: "cry-1", Channel: "crypto", Enabled: true, CredentialEnvPrefix: "cry"},
|
||||
})
|
||||
now := time.Date(2026, 7, 10, 12, 0, 0, 0, time.UTC)
|
||||
|
||||
// 两条 pending:一条在冷却窗内(应恢复),一条建单于 40min 前(> 30min 冷却窗,应跳过)。
|
||||
loader := func(context.Context) ([]crypto.PendingReservation, error) {
|
||||
return []crypto.PendingReservation{
|
||||
{AccountID: "cry-1", AmountMinor: 29990000, ProviderRef: "CRYPTO-PAY-A-263", ReservedAt: now.Add(-5 * time.Minute)},
|
||||
{AccountID: "cry-1", AmountMinor: 29990000, ProviderRef: "CRYPTO-PAY-B-777", ReservedAt: now.Add(-40 * time.Minute)},
|
||||
}, nil
|
||||
}
|
||||
p := crypto.New(reg, crypto.WithReservationLoader(loader), crypto.WithNow(func() time.Time { return now }))
|
||||
if err := p.Warm(context.Background()); err != nil {
|
||||
t.Fatalf("warm: %v", err)
|
||||
}
|
||||
res := p.GetReserved()
|
||||
inWindow := addr + "/" + strconv.FormatInt(29990000+263, 10)
|
||||
expired := addr + "/" + strconv.FormatInt(29990000+777, 10)
|
||||
if _, ok := res[inWindow]; !ok {
|
||||
t.Fatalf("冷却窗内的预留应恢复, got %v", res)
|
||||
}
|
||||
if _, ok := res[expired]; ok {
|
||||
t.Fatalf("超冷却窗的预留不应恢复, got %v", res)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user