@@ -3,6 +3,7 @@ package tbtcpg_test
33import (
44 "reflect"
55 "testing"
6+ "time"
67
78 "github.com/go-test/deep"
89 "github.com/ipfs/go-log"
@@ -13,6 +14,179 @@ import (
1314 "github.com/keep-network/keep-core/pkg/tbtcpg/internal/test"
1415)
1516
17+ func TestDepositSweepLookBackBlocks (t * testing.T ) {
18+ // The look-back period should be 30 days at 12 seconds per block,
19+ // matching the value used by MovedFundsSweepLookBackBlocks.
20+ expectedValue := uint64 (216000 )
21+
22+ if tbtcpg .DepositSweepLookBackBlocks != expectedValue {
23+ t .Errorf (
24+ "unexpected DepositSweepLookBackBlocks\n " +
25+ "expected: %d\n " +
26+ "actual: %d" ,
27+ expectedValue ,
28+ tbtcpg .DepositSweepLookBackBlocks ,
29+ )
30+ }
31+ }
32+
33+ func TestDepositSweepTask_FindDepositsToSweep_BoundedLookback (t * testing.T ) {
34+ // When the current block (300000) exceeds the look-back window
35+ // (216000 blocks), the filter start block should be bounded:
36+ // filterStartBlock = 300000 - 216000 = 84000.
37+ currentBlock := uint64 (300000 )
38+ expectedStartBlock := currentBlock - tbtcpg .DepositSweepLookBackBlocks
39+
40+ walletPublicKeyHash := hexToByte20 (
41+ "7670343fc00ccc2d0cd65360e6ad400697ea0fed" ,
42+ )
43+
44+ tbtcChain := tbtcpg .NewLocalChain ()
45+ btcChain := tbtcpg .NewLocalBitcoinChain ()
46+
47+ blockCounter := tbtcpg .NewMockBlockCounter ()
48+ blockCounter .SetCurrentBlock (currentBlock )
49+ tbtcChain .SetBlockCounter (blockCounter )
50+
51+ tbtcChain .SetDepositMinAge (3600 )
52+
53+ fundingTxHash := hashFromString (
54+ "a8c3b3c1975094550d481bdffdee1b7b7613dd74dbce37a5f6dce7fd9ac0ace1" ,
55+ )
56+
57+ tbtcChain .SetDepositRequest (
58+ fundingTxHash ,
59+ uint32 (1 ),
60+ & tbtc.DepositChainRequest {
61+ RevealedAt : time .Now ().Add (- 2 * time .Hour ),
62+ SweptAt : time .Unix (0 , 0 ),
63+ },
64+ )
65+
66+ btcChain .SetTransaction (fundingTxHash , & bitcoin.Transaction {})
67+ btcChain .SetTransactionConfirmations (
68+ fundingTxHash ,
69+ tbtc .DepositSweepRequiredFundingTxConfirmations ,
70+ )
71+
72+ // Register events under the filter with the bounded start block.
73+ // The production code will query with StartBlock = expectedStartBlock,
74+ // so the event registration must use the same filter key.
75+ err := tbtcChain .AddPastDepositRevealedEvent (
76+ & tbtc.DepositRevealedEventFilter {
77+ StartBlock : expectedStartBlock ,
78+ WalletPublicKeyHash : [][20 ]byte {walletPublicKeyHash },
79+ },
80+ & tbtc.DepositRevealedEvent {
81+ BlockNumber : 290000 ,
82+ WalletPublicKeyHash : walletPublicKeyHash ,
83+ FundingTxHash : fundingTxHash ,
84+ FundingOutputIndex : 1 ,
85+ },
86+ )
87+ if err != nil {
88+ t .Fatal (err )
89+ }
90+
91+ task := tbtcpg .NewDepositSweepTask (tbtcChain , btcChain )
92+
93+ deposits , err := task .FindDepositsToSweep (
94+ & testutils.MockLogger {},
95+ walletPublicKeyHash ,
96+ 5 ,
97+ )
98+ if err != nil {
99+ t .Fatal (err )
100+ }
101+
102+ if len (deposits ) != 1 {
103+ t .Fatalf ("expected 1 deposit, got %d" , len (deposits ))
104+ }
105+
106+ if deposits [0 ].FundingTxHash != fundingTxHash {
107+ t .Errorf ("unexpected funding tx hash" )
108+ }
109+
110+ if deposits [0 ].FundingOutputIndex != 1 {
111+ t .Errorf ("unexpected funding output index" )
112+ }
113+ }
114+
115+ func TestDepositSweepTask_FindDepositsToSweep_UnderflowGuard (t * testing.T ) {
116+ // When the current block is less than the look-back window, the filter
117+ // start block should remain 0 to avoid underflow.
118+ currentBlock := uint64 (100000 )
119+
120+ walletPublicKeyHash := hexToByte20 (
121+ "7670343fc00ccc2d0cd65360e6ad400697ea0fed" ,
122+ )
123+
124+ tbtcChain := tbtcpg .NewLocalChain ()
125+ btcChain := tbtcpg .NewLocalBitcoinChain ()
126+
127+ blockCounter := tbtcpg .NewMockBlockCounter ()
128+ blockCounter .SetCurrentBlock (currentBlock )
129+ tbtcChain .SetBlockCounter (blockCounter )
130+
131+ tbtcChain .SetDepositMinAge (3600 )
132+
133+ fundingTxHash := hashFromString (
134+ "d91868ca43db4deb96047d727a5e782f282864fde2d9364f8c562c8998ba64bf" ,
135+ )
136+
137+ tbtcChain .SetDepositRequest (
138+ fundingTxHash ,
139+ uint32 (1 ),
140+ & tbtc.DepositChainRequest {
141+ RevealedAt : time .Now ().Add (- 2 * time .Hour ),
142+ SweptAt : time .Unix (0 , 0 ),
143+ },
144+ )
145+
146+ btcChain .SetTransaction (fundingTxHash , & bitcoin.Transaction {})
147+ btcChain .SetTransactionConfirmations (
148+ fundingTxHash ,
149+ tbtc .DepositSweepRequiredFundingTxConfirmations ,
150+ )
151+
152+ // Register events under the filter with StartBlock = 0,
153+ // since the underflow guard should keep the filter at 0.
154+ err := tbtcChain .AddPastDepositRevealedEvent (
155+ & tbtc.DepositRevealedEventFilter {
156+ StartBlock : 0 ,
157+ WalletPublicKeyHash : [][20 ]byte {walletPublicKeyHash },
158+ },
159+ & tbtc.DepositRevealedEvent {
160+ BlockNumber : 90000 ,
161+ WalletPublicKeyHash : walletPublicKeyHash ,
162+ FundingTxHash : fundingTxHash ,
163+ FundingOutputIndex : 1 ,
164+ },
165+ )
166+ if err != nil {
167+ t .Fatal (err )
168+ }
169+
170+ task := tbtcpg .NewDepositSweepTask (tbtcChain , btcChain )
171+
172+ deposits , err := task .FindDepositsToSweep (
173+ & testutils.MockLogger {},
174+ walletPublicKeyHash ,
175+ 5 ,
176+ )
177+ if err != nil {
178+ t .Fatal (err )
179+ }
180+
181+ if len (deposits ) != 1 {
182+ t .Fatalf ("expected 1 deposit, got %d" , len (deposits ))
183+ }
184+
185+ if deposits [0 ].FundingTxHash != fundingTxHash {
186+ t .Errorf ("unexpected funding tx hash" )
187+ }
188+ }
189+
16190func TestDepositSweepTask_FindDepositsToSweep (t * testing.T ) {
17191 err := log .SetLogLevel ("*" , "DEBUG" )
18192 if err != nil {
@@ -31,6 +205,20 @@ func TestDepositSweepTask_FindDepositsToSweep(t *testing.T) {
31205
32206 tbtcChain .SetDepositMinAge (scenario .ChainParameters .DepositMinAge )
33207
208+ // Wire the MockBlockCounter using the scenario's current
209+ // block value. FindDepositsToSweep requires a block
210+ // counter to compute the bounded lookback window.
211+ blockCounter := tbtcpg .NewMockBlockCounter ()
212+ blockCounter .SetCurrentBlock (scenario .ChainParameters .CurrentBlock )
213+ tbtcChain .SetBlockCounter (blockCounter )
214+
215+ // Compute the expected filter start block using the same
216+ // logic as the production code.
217+ filterStartBlock := uint64 (0 )
218+ if scenario .ChainParameters .CurrentBlock > tbtcpg .DepositSweepLookBackBlocks {
219+ filterStartBlock = scenario .ChainParameters .CurrentBlock - tbtcpg .DepositSweepLookBackBlocks
220+ }
221+
34222 // Chain setup.
35223 for _ , deposit := range scenario .Deposits {
36224 tbtcChain .SetDepositRequest (
@@ -48,7 +236,10 @@ func TestDepositSweepTask_FindDepositsToSweep(t *testing.T) {
48236 )
49237
50238 err := tbtcChain .AddPastDepositRevealedEvent (
51- & tbtc.DepositRevealedEventFilter {WalletPublicKeyHash : [][20 ]byte {deposit .WalletPublicKeyHash }},
239+ & tbtc.DepositRevealedEventFilter {
240+ StartBlock : filterStartBlock ,
241+ WalletPublicKeyHash : [][20 ]byte {deposit .WalletPublicKeyHash },
242+ },
52243 & tbtc.DepositRevealedEvent {
53244 BlockNumber : deposit .RevealBlockNumber ,
54245 WalletPublicKeyHash : deposit .WalletPublicKeyHash ,
0 commit comments