@@ -13,7 +13,6 @@ import (
1313 flowGo "github.com/onflow/flow-go/model/flow"
1414 "github.com/rs/zerolog"
1515 "github.com/sethvargo/go-retry"
16- "golang.org/x/sync/errgroup"
1716
1817 "github.com/onflow/flow-evm-gateway/config"
1918 "github.com/onflow/flow-evm-gateway/metrics"
@@ -33,11 +32,14 @@ type SingleTxPool struct {
3332 keystore * keystore.KeyStore
3433 collector metrics.Collector
3534 // todo add methods to inspect transaction pool state
35+
36+ latestBlockHeader * flow.BlockHeader
3637}
3738
3839var _ TxPool = & SingleTxPool {}
3940
4041func NewSingleTxPool (
42+ ctx context.Context ,
4143 client * CrossSporkClient ,
4244 transactionsPublisher * models.Publisher [* gethTypes.Transaction ],
4345 logger zerolog.Logger ,
@@ -48,7 +50,7 @@ func NewSingleTxPool(
4850 // initialize the available keys metric since it is only updated when sending a tx
4951 collector .AvailableSigningKeys (keystore .AvailableKeys ())
5052
51- return & SingleTxPool {
53+ singleTxPool := & SingleTxPool {
5254 logger : logger .With ().Str ("component" , "tx-pool" ).Logger (),
5355 client : client ,
5456 txPublisher : transactionsPublisher ,
@@ -57,6 +59,10 @@ func NewSingleTxPool(
5759 collector : collector ,
5860 keystore : keystore ,
5961 }
62+
63+ go singleTxPool .updateLatestBlockHeader (ctx )
64+
65+ return singleTxPool
6066}
6167
6268// Add creates a Cadence transaction that wraps the given EVM transaction in
@@ -93,14 +99,14 @@ func (t *SingleTxPool) Add(
9399 return err
94100 }
95101
96- latestBlock , account , err := t .fetchFlowLatestBlockAndCOA (ctx )
102+ account , err := t .client . GetAccount (ctx , t . config . COAAddress )
97103 if err != nil {
98104 return err
99105 }
100106
101107 script := replaceAddresses (runTxScript , t .config .FlowNetworkID )
102108 flowTx , err := t .buildTransaction (
103- latestBlock ,
109+ t . latestBlockHeader ,
104110 account ,
105111 script ,
106112 hexEncodedTx ,
@@ -157,7 +163,7 @@ func (t *SingleTxPool) Add(
157163// buildTransaction creates a Cadence transaction from the provided script,
158164// with the given arguments and signs it with the configured COA account.
159165func (t * SingleTxPool ) buildTransaction (
160- latestBlock * flow.Block ,
166+ latestBlockHeader * flow.BlockHeader ,
161167 account * flow.Account ,
162168 script []byte ,
163169 args ... cadence.Value ,
@@ -168,7 +174,7 @@ func (t *SingleTxPool) buildTransaction(
168174
169175 flowTx := flow .NewTransaction ().
170176 SetScript (script ).
171- SetReferenceBlockID (latestBlock .ID ).
177+ SetReferenceBlockID (latestBlockHeader .ID ).
172178 SetComputeLimit (flowGo .DefaultMaxTransactionGasLimit )
173179
174180 for _ , arg := range args {
@@ -193,37 +199,40 @@ func (t *SingleTxPool) buildTransaction(
193199 }
194200
195201 // now that the transaction is prepared, store the transaction's metadata
196- accKey .SetLockMetadata (flowTx .ID (), latestBlock .Height )
202+ accKey .SetLockMetadata (flowTx .ID (), latestBlockHeader .Height )
197203
198204 t .collector .OperatorBalance (account )
199205
200206 return flowTx , nil
201207}
202208
203- func (t * SingleTxPool ) fetchFlowLatestBlockAndCOA (ctx context.Context ) (
204- * flow.Block ,
205- * flow.Account ,
206- error ,
207- ) {
208- var (
209- g = errgroup.Group {}
210- err1 , err2 error
211- latestBlock * flow.Block
212- account * flow.Account
213- )
214-
215- // execute concurrently so we can speed up all the information we need for tx
216- g .Go (func () error {
217- latestBlock , err1 = t .client .GetLatestBlock (ctx , true )
218- return err1
219- })
220- g .Go (func () error {
221- account , err2 = t .client .GetAccount (ctx , t .config .COAAddress )
222- return err2
223- })
224- if err := g .Wait (); err != nil {
225- return nil , nil , err
209+ func (t * SingleTxPool ) updateLatestBlockHeader (ctx context.Context ) {
210+ if t .latestBlockHeader == nil {
211+ blockHeader , err := t .client .GetLatestBlockHeader (ctx , false )
212+ if err != nil {
213+ t .logger .Error ().Err (err ).Msg (
214+ "failed to update latest Flow block header" ,
215+ )
216+ }
217+ t .latestBlockHeader = blockHeader
226218 }
227219
228- return latestBlock , account , nil
220+ ticker := time .NewTicker (time .Second * 1 )
221+ defer ticker .Stop ()
222+
223+ for {
224+ select {
225+ case <- ctx .Done ():
226+ return
227+ case <- ticker .C :
228+ blockHeader , err := t .client .GetLatestBlockHeader (ctx , false )
229+ if err != nil {
230+ t .logger .Error ().Err (err ).Msg (
231+ "failed to update latest Flow block header" ,
232+ )
233+ continue
234+ }
235+ t .latestBlockHeader = blockHeader
236+ }
237+ }
229238}
0 commit comments