Skip to content

Commit da04f2e

Browse files
committed
Track the latest finalized block header to avoid fetching it on every tx submission
1 parent 25b8222 commit da04f2e

File tree

4 files changed

+50
-39
lines changed

4 files changed

+50
-39
lines changed

bootstrap/bootstrap.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ func (b *Bootstrap) StartAPIServer(ctx context.Context) error {
259259
)
260260
} else {
261261
txPool = requester.NewSingleTxPool(
262+
ctx,
262263
b.client,
263264
b.publishers.Transaction,
264265
b.logger,

services/requester/batch_tx_pool.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ func NewBatchTxPool(
6262
collector.AvailableSigningKeys(keystore.AvailableKeys())
6363

6464
singleTxPool := NewSingleTxPool(
65+
ctx,
6566
client,
6667
transactionsPublisher,
6768
logger,
@@ -161,10 +162,10 @@ func (t *BatchTxPool) processPooledTransactions(ctx context.Context) {
161162
case <-ctx.Done():
162163
return
163164
case <-ticker.C:
164-
latestBlock, account, err := t.fetchFlowLatestBlockAndCOA(ctx)
165+
account, err := t.client.GetAccount(ctx, t.config.COAAddress)
165166
if err != nil {
166167
t.logger.Error().Err(err).Msg(
167-
"failed to get COA / latest Flow block on batch tx submission",
168+
"failed to get COA on batch tx submission",
168169
)
169170
continue
170171
}
@@ -180,7 +181,7 @@ func (t *BatchTxPool) processPooledTransactions(ctx context.Context) {
180181
for address, pooledTxs := range txsGroupedByAddress {
181182
err := t.batchSubmitTransactionsForSameAddress(
182183
ctx,
183-
latestBlock,
184+
t.latestBlockHeader,
184185
account,
185186
pooledTxs,
186187
)
@@ -198,7 +199,7 @@ func (t *BatchTxPool) processPooledTransactions(ctx context.Context) {
198199

199200
func (t *BatchTxPool) batchSubmitTransactionsForSameAddress(
200201
ctx context.Context,
201-
latestBlock *flow.Block,
202+
latestBlockHeader *flow.BlockHeader,
202203
account *flow.Account,
203204
pooledTxs []pooledEvmTx,
204205
) error {
@@ -220,7 +221,7 @@ func (t *BatchTxPool) batchSubmitTransactionsForSameAddress(
220221

221222
script := replaceAddresses(batchRunTxScript, t.config.FlowNetworkID)
222223
flowTx, err := t.buildTransaction(
223-
latestBlock,
224+
latestBlockHeader,
224225
account,
225226
script,
226227
cadence.NewArray(hexEncodedTxs),
@@ -244,7 +245,7 @@ func (t *BatchTxPool) submitSingleTransaction(
244245
ctx context.Context,
245246
hexEncodedTx cadence.String,
246247
) error {
247-
latestBlock, account, err := t.fetchFlowLatestBlockAndCOA(ctx)
248+
account, err := t.client.GetAccount(ctx, t.config.COAAddress)
248249
if err != nil {
249250
return err
250251
}
@@ -256,7 +257,7 @@ func (t *BatchTxPool) submitSingleTransaction(
256257

257258
script := replaceAddresses(runTxScript, t.config.FlowNetworkID)
258259
flowTx, err := t.buildTransaction(
259-
latestBlock,
260+
t.latestBlockHeader,
260261
account,
261262
script,
262263
hexEncodedTx,

services/requester/single_tx_pool.go

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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

3839
var _ TxPool = &SingleTxPool{}
3940

4041
func 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.
159165
func (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
}

tests/helpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func startEmulator(createTestAccounts bool) (*server.EmulatorServer, error) {
9090
GenesisTokenSupply: genesisToken,
9191
WithContracts: true,
9292
Host: "localhost",
93-
TransactionExpiry: 10,
93+
TransactionExpiry: flow.DefaultTransactionExpiry,
9494
TransactionMaxGasLimit: flow.DefaultMaxTransactionGasLimit,
9595
SetupEVMEnabled: true,
9696
SetupVMBridgeEnabled: false,

0 commit comments

Comments
 (0)