44 "context"
55 "log/slog"
66 "math/big"
7+ "sync"
78 "sync/atomic"
89 "time"
910
@@ -22,7 +23,7 @@ type blockTracker struct {
2223 blocks * lru.Cache [uint64 , * types.Block ]
2324 client EthClient
2425 log * slog.Logger
25- checkTrigger chan struct {}
26+ checkCond * sync. Cond
2627}
2728
2829func NewBlockTracker (client EthClient , log * slog.Logger ) (* blockTracker , error ) {
@@ -36,7 +37,7 @@ func NewBlockTracker(client EthClient, log *slog.Logger) (*blockTracker, error)
3637 blocks : cache ,
3738 client : client ,
3839 log : log ,
39- checkTrigger : make ( chan struct {}, 1 ),
40+ checkCond : sync . NewCond ( & sync. Mutex {} ),
4041 }, nil
4142}
4243
@@ -73,11 +74,9 @@ func (b *blockTracker) Start(ctx context.Context) <-chan struct{} {
7374}
7475
7576func (b * blockTracker ) triggerCheck () {
76- select {
77- case b .checkTrigger <- struct {}{}:
78- default :
79- // Non-blocking send, if channel is full, we skip
80- }
77+ b .checkCond .L .Lock ()
78+ b .checkCond .Broadcast ()
79+ b .checkCond .L .Unlock ()
8180}
8281
8382func (b * blockTracker ) LatestBlockNumber () uint64 {
@@ -89,32 +88,43 @@ func (b *blockTracker) CheckTxnInclusion(
8988 txHash common.Hash ,
9089 blockNumber uint64 ,
9190) (bool , error ) {
92- WaitForBlock:
93- for {
94- select {
95- case <- ctx .Done ():
96- return false , ctx .Err ()
97- case <- b .checkTrigger :
98- if blockNumber <= b .latestBlockNo .Load () {
99- break WaitForBlock
100- }
91+ if blockNumber <= b .latestBlockNo .Load () {
92+ return b .checkTxnInclusion (ctx , txHash , blockNumber )
93+ }
94+
95+ waitCh := make (chan struct {})
96+ go func () {
97+ b .checkCond .L .Lock ()
98+ defer b .checkCond .L .Unlock ()
99+ for blockNumber > b .latestBlockNo .Load () {
100+ b .checkCond .Wait ()
101101 }
102+ close (waitCh )
103+ }()
104+
105+ select {
106+ case <- ctx .Done ():
107+ return false , ctx .Err ()
108+ case <- waitCh :
109+ return b .checkTxnInclusion (ctx , txHash , blockNumber )
102110 }
111+ }
103112
113+ func (b * blockTracker ) checkTxnInclusion (ctx context.Context , txHash common.Hash , blockNumber uint64 ) (bool , error ) {
114+ var err error
104115 block , ok := b .blocks .Get (blockNumber )
105116 if ! ok {
106- block , err : = b .client .BlockByNumber (ctx , big .NewInt (int64 (blockNumber )))
117+ block , err = b .client .BlockByNumber (ctx , big .NewInt (int64 (blockNumber )))
107118 if err != nil {
108119 b .log .Error ("Failed to get block by number" , "error" , err , "blockNumber" , blockNumber )
109120 return false , err
110121 }
111122 _ = b .blocks .Add (blockNumber , block )
112123 }
113124
114- for _ , tx := range block .Transactions () {
115- if tx .Hash ().Cmp (txHash ) == 0 {
116- return true , nil
117- }
125+ if txn := block .Transaction (txHash ); txn != nil {
126+ return true , nil
118127 }
128+
119129 return false , nil
120130}
0 commit comments