Skip to content

Commit ed88325

Browse files
committed
Update tx submission logic to only fetch a single account key from the COA
1 parent 25daf5b commit ed88325

File tree

4 files changed

+36
-54
lines changed

4 files changed

+36
-54
lines changed

services/requester/batch_tx_pool.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,10 @@ func (t *BatchTxPool) processPooledTransactions(ctx context.Context) {
161161
case <-ctx.Done():
162162
return
163163
case <-ticker.C:
164-
latestBlock, account, err := t.fetchFlowLatestBlockAndCOA(ctx)
164+
latestBlock, err := t.client.GetLatestBlock(ctx, true)
165165
if err != nil {
166166
t.logger.Error().Err(err).Msg(
167-
"failed to get COA / latest Flow block on batch tx submission",
167+
"failed to get latest Flow block on batch tx submission",
168168
)
169169
continue
170170
}
@@ -181,7 +181,6 @@ func (t *BatchTxPool) processPooledTransactions(ctx context.Context) {
181181
err := t.batchSubmitTransactionsForSameAddress(
182182
ctx,
183183
latestBlock,
184-
account,
185184
pooledTxs,
186185
)
187186
if err != nil {
@@ -199,7 +198,6 @@ func (t *BatchTxPool) processPooledTransactions(ctx context.Context) {
199198
func (t *BatchTxPool) batchSubmitTransactionsForSameAddress(
200199
ctx context.Context,
201200
latestBlock *flow.Block,
202-
account *flow.Account,
203201
pooledTxs []pooledEvmTx,
204202
) error {
205203
// Sort the transactions based on their nonce, to make sure
@@ -220,8 +218,8 @@ func (t *BatchTxPool) batchSubmitTransactionsForSameAddress(
220218

221219
script := replaceAddresses(runTxScript, t.config.FlowNetworkID)
222220
flowTx, err := t.buildTransaction(
221+
ctx,
223222
latestBlock,
224-
account,
225223
script,
226224
cadence.NewArray(hexEncodedTxs),
227225
coinbaseAddress,
@@ -244,7 +242,7 @@ func (t *BatchTxPool) submitSingleTransaction(
244242
ctx context.Context,
245243
hexEncodedTx cadence.String,
246244
) error {
247-
latestBlock, account, err := t.fetchFlowLatestBlockAndCOA(ctx)
245+
latestBlock, err := t.client.GetLatestBlock(ctx, true)
248246
if err != nil {
249247
return err
250248
}
@@ -256,8 +254,8 @@ func (t *BatchTxPool) submitSingleTransaction(
256254

257255
script := replaceAddresses(runTxScript, t.config.FlowNetworkID)
258256
flowTx, err := t.buildTransaction(
257+
ctx,
259258
latestBlock,
260-
account,
261259
script,
262260
cadence.NewArray([]cadence.Value{hexEncodedTx}),
263261
coinbaseAddress,

services/requester/keystore/account_key.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,31 @@ func (k *AccountKey) SetLockMetadata(txID flowsdk.Identifier, referenceBlockHeig
5454
// SetProposerPayerAndSign sets the proposer, payer, and signs the transaction with the key.
5555
func (k *AccountKey) SetProposerPayerAndSign(
5656
tx *flowsdk.Transaction,
57-
account *flowsdk.Account,
57+
address flowsdk.Address,
58+
acckey *flowsdk.AccountKey,
5859
) error {
59-
if k.Address != account.Address {
60+
if acckey == nil {
61+
return fmt.Errorf("nil account key provided for address %s (index %d)", address, k.Index)
62+
}
63+
64+
if k.Address != address {
6065
return fmt.Errorf(
61-
"expected address: %v, got address: %v",
66+
"expected address: %s, got address: %s",
6267
k.Address,
63-
account.Address,
68+
address,
6469
)
6570
}
66-
if k.Index >= uint32(len(account.Keys)) {
71+
72+
if k.Index != acckey.Index {
6773
return fmt.Errorf(
68-
"key index: %d exceeds keys length: %d",
74+
"expected account key with index: %d, got key with index: %d",
6975
k.Index,
70-
len(account.Keys),
76+
acckey.Index,
7177
)
7278
}
73-
seqNumber := account.Keys[k.Index].SequenceNumber
7479

7580
return tx.
76-
SetProposalKey(k.Address, k.Index, seqNumber).
81+
SetProposalKey(k.Address, k.Index, acckey.SequenceNumber).
7782
SetPayer(k.Address).
7883
SignEnvelope(k.Address, k.Index, k.Signer)
7984
}

services/requester/keystore/key_store_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func TestKeySigning(t *testing.T) {
200200
}
201201
tx := sdk.NewTransaction()
202202

203-
err = key.SetProposerPayerAndSign(tx, account)
203+
err = key.SetProposerPayerAndSign(tx, address, accountKey)
204204
require.NoError(t, err)
205205

206206
assert.Equal(t, account.Address, tx.ProposalKey.Address)

services/requester/single_tx_pool.go

Lines changed: 16 additions & 37 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"
@@ -93,15 +92,15 @@ func (t *SingleTxPool) Add(
9392
return err
9493
}
9594

96-
latestBlock, account, err := t.fetchFlowLatestBlockAndCOA(ctx)
95+
latestBlock, err := t.client.GetLatestBlock(ctx, true)
9796
if err != nil {
9897
return err
9998
}
10099

101100
script := replaceAddresses(runTxScript, t.config.FlowNetworkID)
102101
flowTx, err := t.buildTransaction(
102+
ctx,
103103
latestBlock,
104-
account,
105104
script,
106105
cadence.NewArray([]cadence.Value{hexEncodedTx}),
107106
coinbaseAddress,
@@ -157,8 +156,8 @@ func (t *SingleTxPool) Add(
157156
// buildTransaction creates a Cadence transaction from the provided script,
158157
// with the given arguments and signs it with the configured COA account.
159158
func (t *SingleTxPool) buildTransaction(
159+
ctx context.Context,
160160
latestBlock *flow.Block,
161-
account *flow.Account,
162161
script []byte,
163162
args ...cadence.Value,
164163
) (*flow.Transaction, error) {
@@ -177,53 +176,33 @@ func (t *SingleTxPool) buildTransaction(
177176
}
178177
}
179178

180-
// building and signing transactions should be blocking,
181-
// so we don't have keys conflict
182-
t.mux.Lock()
183-
defer t.mux.Unlock()
179+
accKey, err := t.fetchSigningAccountKey()
180+
if err != nil {
181+
return nil, err
182+
}
184183

185-
accKey, err := t.keystore.Take()
184+
coaAddress := t.config.COAAddress
185+
accountKey, err := t.client.GetAccountKeyAtLatestBlock(ctx, coaAddress, accKey.Index)
186186
if err != nil {
187187
return nil, err
188188
}
189189

190-
if err := accKey.SetProposerPayerAndSign(flowTx, account); err != nil {
190+
if err := accKey.SetProposerPayerAndSign(flowTx, coaAddress, accountKey); err != nil {
191191
accKey.Done()
192192
return nil, err
193193
}
194194

195195
// now that the transaction is prepared, store the transaction's metadata
196196
accKey.SetLockMetadata(flowTx.ID(), latestBlock.Height)
197197

198-
t.collector.OperatorBalance(account)
199-
200198
return flowTx, nil
201199
}
202200

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
226-
}
201+
func (t *SingleTxPool) fetchSigningAccountKey() (*keystore.AccountKey, error) {
202+
// building and signing transactions should be
203+
// blocking, so we don't have conflicts with keys.
204+
t.mux.Lock()
205+
defer t.mux.Unlock()
227206

228-
return latestBlock, account, nil
207+
return t.keystore.Take()
229208
}

0 commit comments

Comments
 (0)