From 60481c9e82517fac8bd4da8c362c18f92119ef36 Mon Sep 17 00:00:00 2001 From: Daniel Wasserman Date: Thu, 19 Oct 2023 15:52:18 -0400 Subject: [PATCH 1/6] Feat: add gas block cache with TestGetGasBlock --- ethergo/submitter/export_test.go | 10 +++++- ethergo/submitter/submitter.go | 52 +++++++++++++++++++---------- ethergo/submitter/submitter_test.go | 36 +++++++++++++++++++- 3 files changed, 79 insertions(+), 19 deletions(-) diff --git a/ethergo/submitter/export_test.go b/ethergo/submitter/export_test.go index 4b9b8798f8..5cdcf3142d 100644 --- a/ethergo/submitter/export_test.go +++ b/ethergo/submitter/export_test.go @@ -2,6 +2,8 @@ package submitter import ( "context" + "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -11,7 +13,6 @@ import ( "github.com/synapsecns/sanguine/ethergo/submitter/config" "github.com/synapsecns/sanguine/ethergo/submitter/db" "go.opentelemetry.io/otel/attribute" - "math/big" ) // CopyTransactOpts exports copyTransactOpts for testing. @@ -85,6 +86,8 @@ type TestTransactionSubmitter interface { // SetGasPrice exports setGasPrice for testing. SetGasPrice(ctx context.Context, client client.EVM, transactor *bind.TransactOpts, bigChainID *big.Int, prevTx *types.Transaction) (err error) + // GetGasBlock exports getGasBlock for testing. + GetGasBlock(ctx context.Context, client client.EVM, chainID int) (gasBlock *types.Header, err error) // GetNonce exports getNonce for testing. GetNonce(parentCtx context.Context, chainID *big.Int, address common.Address) (_ uint64, err error) // CheckAndSetConfirmation exports checkAndSetConfirmation for testing. @@ -97,6 +100,11 @@ func (t *txSubmitterImpl) SetGasPrice(ctx context.Context, client client.EVM, return t.setGasPrice(ctx, client, transactor, bigChainID, prevTx) } +// GetGasBlock exports getGasBlock for testing. +func (t *txSubmitterImpl) GetGasBlock(ctx context.Context, client client.EVM, chainID int) (gasBlock *types.Header, err error) { + return t.getGasBlock(ctx, client, chainID) +} + // GetNonce exports getNonce for testing. func (t *txSubmitterImpl) GetNonce(parentCtx context.Context, chainID *big.Int, address common.Address) (_ uint64, err error) { return t.getNonce(parentCtx, chainID, address) diff --git a/ethergo/submitter/submitter.go b/ethergo/submitter/submitter.go index 4c01c4198c..af3ef21f3c 100644 --- a/ethergo/submitter/submitter.go +++ b/ethergo/submitter/submitter.go @@ -4,6 +4,13 @@ import ( "context" "errors" "fmt" + "math" + "math/big" + "reflect" + "runtime" + "sync" + "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -21,12 +28,6 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "golang.org/x/sync/errgroup" - "math" - "math/big" - "reflect" - "runtime" - "sync" - "time" ) var logger = log.Logger("ethergo-submitter") @@ -63,6 +64,8 @@ type txSubmitterImpl struct { // to prevent memory leaks, this has a buffer of 1. // callers adding to this channel should not block. retryNow chan bool + // gasBlockCache is used to cache the gas block for a given chain. + gasBlockCache map[int]*types.Header // config is the config for the transaction submitter. config config.IConfig } @@ -77,14 +80,15 @@ type ClientFetcher interface { // NewTransactionSubmitter creates a new transaction submitter. func NewTransactionSubmitter(metrics metrics.Handler, signer signer.Signer, fetcher ClientFetcher, db db.Service, config config.IConfig) TransactionSubmitter { return &txSubmitterImpl{ - db: db, - config: config, - metrics: metrics, - signer: signer, - fetcher: fetcher, - nonceMux: mapmutex.NewStringerMapMutex(), - statusMux: mapmutex.NewStringMapMutex(), - retryNow: make(chan bool, 1), + db: db, + config: config, + metrics: metrics, + signer: signer, + fetcher: fetcher, + nonceMux: mapmutex.NewStringerMapMutex(), + statusMux: mapmutex.NewStringMapMutex(), + retryNow: make(chan bool, 1), + gasBlockCache: map[int]*types.Header{}, } } @@ -371,9 +375,10 @@ func (t *txSubmitterImpl) setGasPrice(ctx context.Context, client client.EVM, //nolint: nestif if prevTx != nil { // TODO: cache - gasBlock, err := t.getGasBlock(ctx, client) + gasBlock, err := t.getGasBlock(ctx, client, chainID) if err != nil { span.AddEvent("could not get gas block", trace.WithAttributes(attribute.String("error", err.Error()))) + return err } // if the prev tx was greater than this one, we should bump the gas price from that point @@ -392,7 +397,7 @@ func (t *txSubmitterImpl) setGasPrice(ctx context.Context, client client.EVM, } // getGasBlock gets the gas block for the given chain. -func (t *txSubmitterImpl) getGasBlock(ctx context.Context, chainClient client.EVM) (gasBlock *types.Header, err error) { +func (t *txSubmitterImpl) getGasBlock(ctx context.Context, chainClient client.EVM, chainID int) (gasBlock *types.Header, err error) { ctx, span := t.metrics.Tracer().Start(ctx, "submitter.getGasBlock") defer func() { metrics.EndSpanWithErr(span, err) @@ -407,10 +412,23 @@ func (t *txSubmitterImpl) getGasBlock(ctx context.Context, chainClient client.EV return nil }, retry.WithMin(time.Millisecond*50), retry.WithMax(time.Second*3), retry.WithMaxAttempts(4)) + // if we can't get the current gas block, attempt to load it from the cache if err != nil { - return nil, fmt.Errorf("could not get gas block: %w", err) + var ok bool + gasBlock, ok = t.gasBlockCache[chainID] + if ok { + span.AddEvent("could not get gas block; using cached value", trace.WithAttributes( + attribute.String("error", err.Error()), + attribute.String("blockNumber", bigPtrToString(gasBlock.Number)), + )) + } else { + return nil, fmt.Errorf("could not get gas block: %w", err) + } } + // cache the latest gas block + t.gasBlockCache[chainID] = gasBlock + return gasBlock, nil } diff --git a/ethergo/submitter/submitter_test.go b/ethergo/submitter/submitter_test.go index 4d9c9119bb..6c1a8824a1 100644 --- a/ethergo/submitter/submitter_test.go +++ b/ethergo/submitter/submitter_test.go @@ -2,6 +2,8 @@ package submitter_test import ( "fmt" + "math/big" + "github.com/brianvoe/gofakeit/v6" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/core/types" @@ -20,7 +22,6 @@ import ( dbMocks "github.com/synapsecns/sanguine/ethergo/submitter/db/mocks" submitterMocks "github.com/synapsecns/sanguine/ethergo/submitter/mocks" "github.com/synapsecns/sanguine/ethergo/util" - "math/big" ) func (s *SubmitterSuite) TestSetGasPrice() { @@ -72,6 +73,39 @@ func (s *SubmitterSuite) TestSetGasPrice() { // 5. Test with bump and max (TODO) } +func (s *SubmitterSuite) TestGetGasBlock() { + wall, err := wallet.FromRandom() + s.Require().NoError(err) + + signer := localsigner.NewSigner(wall.PrivateKey()) + + chainID := s.testBackends[0].GetBigChainID() + client := new(clientMocks.EVM) + + cfg := &config.Config{} + ts := submitter.NewTestTransactionSubmitter(s.metrics, signer, s, s.store, cfg) + + // 1. Test with failed HeaderByNumber RPC call; Error is expected. + mockErrMsg := "mock error" + client.On(testsuite.GetFunctionName(client.HeaderByNumber), mock.Anything, mock.Anything).Times(5).Return(nil, fmt.Errorf(mockErrMsg)) + gasBlock, err := ts.GetGasBlock(s.GetTestContext(), client, int(chainID.Int64())) + s.Nil(gasBlock) + s.NotNil(err) + + // 2. Test with successful HeaderByNumber RPC call. + currentHeader := &types.Header{Number: big.NewInt(1)} + client.On(testsuite.GetFunctionName(client.HeaderByNumber), mock.Anything, mock.Anything).Once().Return(currentHeader, nil) + gasBlock, err = ts.GetGasBlock(s.GetTestContext(), client, int(chainID.Int64())) + s.Nil(err) + s.Equal(gasBlock.Number.String(), currentHeader.Number.String()) + + // 3. Test with failed HeaderByNumber RPC call; the cached value should be used. + client.On(testsuite.GetFunctionName(client.HeaderByNumber), mock.Anything, mock.Anything).Times(5).Return(nil, fmt.Errorf(mockErrMsg)) + gasBlock, err = ts.GetGasBlock(s.GetTestContext(), client, int(chainID.Int64())) + s.Nil(err) + s.Equal(gasBlock.Number.String(), currentHeader.Number.String()) +} + func (s *SubmitterSuite) TestGetNonce() { chainID := s.testBackends[0].GetBigChainID() From 62f02fbc1d6b745049f5c01c63db7f7e130b440f Mon Sep 17 00:00:00 2001 From: Daniel Wasserman Date: Thu, 19 Oct 2023 15:53:53 -0400 Subject: [PATCH 2/6] Cleanup: use Require().NoError() --- ethergo/submitter/submitter_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ethergo/submitter/submitter_test.go b/ethergo/submitter/submitter_test.go index 6c1a8824a1..b28801db70 100644 --- a/ethergo/submitter/submitter_test.go +++ b/ethergo/submitter/submitter_test.go @@ -84,6 +84,7 @@ func (s *SubmitterSuite) TestGetGasBlock() { cfg := &config.Config{} ts := submitter.NewTestTransactionSubmitter(s.metrics, signer, s, s.store, cfg) + currentHeader := &types.Header{Number: big.NewInt(1)} // 1. Test with failed HeaderByNumber RPC call; Error is expected. mockErrMsg := "mock error" @@ -93,16 +94,15 @@ func (s *SubmitterSuite) TestGetGasBlock() { s.NotNil(err) // 2. Test with successful HeaderByNumber RPC call. - currentHeader := &types.Header{Number: big.NewInt(1)} client.On(testsuite.GetFunctionName(client.HeaderByNumber), mock.Anything, mock.Anything).Once().Return(currentHeader, nil) gasBlock, err = ts.GetGasBlock(s.GetTestContext(), client, int(chainID.Int64())) - s.Nil(err) + s.Require().NoError(err) s.Equal(gasBlock.Number.String(), currentHeader.Number.String()) // 3. Test with failed HeaderByNumber RPC call; the cached value should be used. client.On(testsuite.GetFunctionName(client.HeaderByNumber), mock.Anything, mock.Anything).Times(5).Return(nil, fmt.Errorf(mockErrMsg)) gasBlock, err = ts.GetGasBlock(s.GetTestContext(), client, int(chainID.Int64())) - s.Nil(err) + s.Require().NoError(err) s.Equal(gasBlock.Number.String(), currentHeader.Number.String()) } From db17819a82762d296947a52cec99f95cbd392f92 Mon Sep 17 00:00:00 2001 From: Daniel Wasserman Date: Thu, 19 Oct 2023 16:16:03 -0400 Subject: [PATCH 3/6] Cleanup: remove todo --- ethergo/submitter/submitter.go | 1 - 1 file changed, 1 deletion(-) diff --git a/ethergo/submitter/submitter.go b/ethergo/submitter/submitter.go index af3ef21f3c..69fbacf498 100644 --- a/ethergo/submitter/submitter.go +++ b/ethergo/submitter/submitter.go @@ -374,7 +374,6 @@ func (t *txSubmitterImpl) setGasPrice(ctx context.Context, client client.EVM, //nolint: nestif if prevTx != nil { - // TODO: cache gasBlock, err := t.getGasBlock(ctx, client, chainID) if err != nil { span.AddEvent("could not get gas block", trace.WithAttributes(attribute.String("error", err.Error()))) From 7da9e5cea9969c72d4a0baad84bbc9b09397e4eb Mon Sep 17 00:00:00 2001 From: Trajan0x Date: Thu, 19 Oct 2023 21:19:28 +0100 Subject: [PATCH 4/6] action fix --- .github/workflows/go.yml | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 5252a0f98d..c81b407fc8 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -471,13 +471,23 @@ jobs: # Fail if files need regeneration # TODO: this can run into a bit of a race condition if any other label is removed/added while this is run, look into fixing this by dispatching another workflow - name: Add Label +# if: ${{ !contains(fromJson(needs.pr_metadata.outputs.labels), format('needs-go-generate-{0}', matrix.package)) && steps.verify-changed-files.outputs.files_changed == 'true' }} +# uses: andymckay/labeler@3a4296e9dcdf9576b0456050db78cfd34853f260 +# with: +# add-labels: 'needs-go-generate-${{matrix.package}}' +# repo-token: ${{ secrets.GITHUB_TOKEN }} +# issue-number: ${{ needs.pr_metadata.outputs.issue_number }} + + uses: actions/github-script@v6 if: ${{ !contains(fromJson(needs.pr_metadata.outputs.labels), format('needs-go-generate-{0}', matrix.package)) && steps.verify-changed-files.outputs.files_changed == 'true' }} - uses: andymckay/labeler@3a4296e9dcdf9576b0456050db78cfd34853f260 with: - add-labels: 'needs-go-generate-${{matrix.package}}' - repo-token: ${{ secrets.GITHUB_TOKEN }} - issue-number: ${{ needs.pr_metadata.outputs.issue_number }} - + script: | + github.rest.issues.addLabels({ + issue_number: ${{ needs.pr_metadata.outputs.issue_number }}, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ["needs-go-generate-${{matrix.package}}"] + }) - name: Remove Label if: ${{ contains(fromJson(needs.pr_metadata.outputs.labels), format('needs-go-generate-{0}', matrix.package)) && steps.verify-changed-files.outputs.files_changed != 'true' }} uses: andymckay/labeler@3a4296e9dcdf9576b0456050db78cfd34853f260 From 39a927456af0b5e1f36892d92ee4b13374d52eb7 Mon Sep 17 00:00:00 2001 From: Trajan0x Date: Thu, 19 Oct 2023 21:30:38 +0100 Subject: [PATCH 5/6] remove label --- .github/workflows/go.yml | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c81b407fc8..9790716861 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -471,13 +471,6 @@ jobs: # Fail if files need regeneration # TODO: this can run into a bit of a race condition if any other label is removed/added while this is run, look into fixing this by dispatching another workflow - name: Add Label -# if: ${{ !contains(fromJson(needs.pr_metadata.outputs.labels), format('needs-go-generate-{0}', matrix.package)) && steps.verify-changed-files.outputs.files_changed == 'true' }} -# uses: andymckay/labeler@3a4296e9dcdf9576b0456050db78cfd34853f260 -# with: -# add-labels: 'needs-go-generate-${{matrix.package}}' -# repo-token: ${{ secrets.GITHUB_TOKEN }} -# issue-number: ${{ needs.pr_metadata.outputs.issue_number }} - uses: actions/github-script@v6 if: ${{ !contains(fromJson(needs.pr_metadata.outputs.labels), format('needs-go-generate-{0}', matrix.package)) && steps.verify-changed-files.outputs.files_changed == 'true' }} with: @@ -490,11 +483,15 @@ jobs: }) - name: Remove Label if: ${{ contains(fromJson(needs.pr_metadata.outputs.labels), format('needs-go-generate-{0}', matrix.package)) && steps.verify-changed-files.outputs.files_changed != 'true' }} - uses: andymckay/labeler@3a4296e9dcdf9576b0456050db78cfd34853f260 + uses: actions/github-script@v6 with: - remove-labels: 'needs-go-generate-${{matrix.package}}' - repo-token: ${{ secrets.GITHUB_TOKEN }} - issue-number: ${{ needs.pr_metadata.outputs.issue_number }} + script: | + github.rest.issues.removeLabel({ + issue_number: ${{ needs.pr_metadata.outputs.issue_number }}, + owner: context.repo.owner, + repo: context.repo.repo, + name: ["needs-go-generate-${{matrix.package}}"] + }) remove-label-generation: name: Remove Generate Label From Unused Jobs From 48d19f083e854021cb28a77800b3f4b535ba2bf0 Mon Sep 17 00:00:00 2001 From: Trajan0x Date: Fri, 20 Oct 2023 14:41:42 +0100 Subject: [PATCH 6/6] make gas block thread safe --- agents/go.mod | 1 + agents/go.sum | 2 ++ contrib/promexporter/go.mod | 1 + contrib/promexporter/go.sum | 2 ++ ethergo/go.mod | 1 + ethergo/go.sum | 2 ++ ethergo/submitter/submitter.go | 27 ++++++++++++++------------- services/cctp-relayer/go.mod | 1 + services/cctp-relayer/go.sum | 2 ++ services/omnirpc/go.mod | 1 + services/omnirpc/go.sum | 2 ++ 11 files changed, 29 insertions(+), 13 deletions(-) diff --git a/agents/go.mod b/agents/go.mod index 2820dfab1a..c49d685a7f 100644 --- a/agents/go.mod +++ b/agents/go.mod @@ -44,6 +44,7 @@ require ( require ( dario.cat/mergo v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect + github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect ) require ( diff --git a/agents/go.sum b/agents/go.sum index 6b851ab1fd..1d983338d2 100644 --- a/agents/go.sum +++ b/agents/go.sum @@ -1075,6 +1075,8 @@ github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38i github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/puzpuzpuz/xsync v1.4.3 h1:nS/Iqc4EnpJ8jm/MzJ+e3MUaP2Ys2mqXeEfoxoU0HaM= github.com/puzpuzpuz/xsync v1.4.3/go.mod h1:K98BYhX3k1dQ2M63t1YNVDanbwUPmBCAhNmVrrxfiGg= +github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= +github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/pyroscope-io/client v0.7.2 h1:OX2qdUQsS8RSkn/3C8isD7f/P0YiZQlRbAlecAaj/R8= github.com/pyroscope-io/client v0.7.2/go.mod h1:FEocnjn+Ngzxy6EtU9ZxXWRvQ0+pffkrBxHLnPpxwi8= github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4= diff --git a/contrib/promexporter/go.mod b/contrib/promexporter/go.mod index 7e587ff801..f26743230d 100644 --- a/contrib/promexporter/go.mod +++ b/contrib/promexporter/go.mod @@ -169,6 +169,7 @@ require ( github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/prometheus/tsdb v0.10.0 // indirect + github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/pyroscope-io/client v0.7.2 // indirect github.com/pyroscope-io/godeltaprof v0.1.2 // indirect github.com/pyroscope-io/otel-profiling-go v0.4.0 // indirect diff --git a/contrib/promexporter/go.sum b/contrib/promexporter/go.sum index a7e92e37f3..6e39cf822e 100644 --- a/contrib/promexporter/go.sum +++ b/contrib/promexporter/go.sum @@ -936,6 +936,8 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/puzpuzpuz/xsync v1.4.3 h1:nS/Iqc4EnpJ8jm/MzJ+e3MUaP2Ys2mqXeEfoxoU0HaM= +github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= +github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/pyroscope-io/client v0.7.2 h1:OX2qdUQsS8RSkn/3C8isD7f/P0YiZQlRbAlecAaj/R8= github.com/pyroscope-io/client v0.7.2/go.mod h1:FEocnjn+Ngzxy6EtU9ZxXWRvQ0+pffkrBxHLnPpxwi8= github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4= diff --git a/ethergo/go.mod b/ethergo/go.mod index bc8886f14f..52ccc59ede 100644 --- a/ethergo/go.mod +++ b/ethergo/go.mod @@ -42,6 +42,7 @@ require ( github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.15.1 + github.com/puzpuzpuz/xsync/v2 v2.5.1 github.com/richardwilkes/toolbox v1.74.0 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cast v1.5.0 diff --git a/ethergo/go.sum b/ethergo/go.sum index 72975dfef4..dec7a90b79 100644 --- a/ethergo/go.sum +++ b/ethergo/go.sum @@ -992,6 +992,8 @@ github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= +github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= +github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/pyroscope-io/client v0.7.2 h1:OX2qdUQsS8RSkn/3C8isD7f/P0YiZQlRbAlecAaj/R8= github.com/pyroscope-io/client v0.7.2/go.mod h1:FEocnjn+Ngzxy6EtU9ZxXWRvQ0+pffkrBxHLnPpxwi8= github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4= diff --git a/ethergo/submitter/submitter.go b/ethergo/submitter/submitter.go index 69fbacf498..03b23291c8 100644 --- a/ethergo/submitter/submitter.go +++ b/ethergo/submitter/submitter.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/puzpuzpuz/xsync/v2" "math" "math/big" "reflect" @@ -64,8 +65,8 @@ type txSubmitterImpl struct { // to prevent memory leaks, this has a buffer of 1. // callers adding to this channel should not block. retryNow chan bool - // gasBlockCache is used to cache the gas block for a given chain. - gasBlockCache map[int]*types.Header + // lastGasBlockCache is used to cache the last gas block for a given chain. A new block should still be fetched, if possible. + lastGasBlockCache *xsync.MapOf[int, *types.Header] // config is the config for the transaction submitter. config config.IConfig } @@ -80,15 +81,15 @@ type ClientFetcher interface { // NewTransactionSubmitter creates a new transaction submitter. func NewTransactionSubmitter(metrics metrics.Handler, signer signer.Signer, fetcher ClientFetcher, db db.Service, config config.IConfig) TransactionSubmitter { return &txSubmitterImpl{ - db: db, - config: config, - metrics: metrics, - signer: signer, - fetcher: fetcher, - nonceMux: mapmutex.NewStringerMapMutex(), - statusMux: mapmutex.NewStringMapMutex(), - retryNow: make(chan bool, 1), - gasBlockCache: map[int]*types.Header{}, + db: db, + config: config, + metrics: metrics, + signer: signer, + fetcher: fetcher, + nonceMux: mapmutex.NewStringerMapMutex(), + statusMux: mapmutex.NewStringMapMutex(), + retryNow: make(chan bool, 1), + lastGasBlockCache: xsync.NewIntegerMapOf[int, *types.Header](), } } @@ -414,7 +415,7 @@ func (t *txSubmitterImpl) getGasBlock(ctx context.Context, chainClient client.EV // if we can't get the current gas block, attempt to load it from the cache if err != nil { var ok bool - gasBlock, ok = t.gasBlockCache[chainID] + gasBlock, ok = t.lastGasBlockCache.Load(chainID) if ok { span.AddEvent("could not get gas block; using cached value", trace.WithAttributes( attribute.String("error", err.Error()), @@ -426,7 +427,7 @@ func (t *txSubmitterImpl) getGasBlock(ctx context.Context, chainClient client.EV } // cache the latest gas block - t.gasBlockCache[chainID] = gasBlock + t.lastGasBlockCache.Store(chainID, gasBlock) return gasBlock, nil } diff --git a/services/cctp-relayer/go.mod b/services/cctp-relayer/go.mod index f2f9479256..acbf3a3e2f 100644 --- a/services/cctp-relayer/go.mod +++ b/services/cctp-relayer/go.mod @@ -214,6 +214,7 @@ require ( github.com/prometheus/procfs v0.9.0 // indirect github.com/prometheus/tsdb v0.10.0 // indirect github.com/puzpuzpuz/xsync v1.4.3 // indirect + github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/pyroscope-io/client v0.7.2 // indirect github.com/pyroscope-io/godeltaprof v0.1.2 // indirect github.com/pyroscope-io/otel-profiling-go v0.4.0 // indirect diff --git a/services/cctp-relayer/go.sum b/services/cctp-relayer/go.sum index 566fb99f30..95cb711ae1 100644 --- a/services/cctp-relayer/go.sum +++ b/services/cctp-relayer/go.sum @@ -1019,6 +1019,8 @@ github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38i github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/puzpuzpuz/xsync v1.4.3 h1:nS/Iqc4EnpJ8jm/MzJ+e3MUaP2Ys2mqXeEfoxoU0HaM= github.com/puzpuzpuz/xsync v1.4.3/go.mod h1:K98BYhX3k1dQ2M63t1YNVDanbwUPmBCAhNmVrrxfiGg= +github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= +github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/pyroscope-io/client v0.7.2 h1:OX2qdUQsS8RSkn/3C8isD7f/P0YiZQlRbAlecAaj/R8= github.com/pyroscope-io/client v0.7.2/go.mod h1:FEocnjn+Ngzxy6EtU9ZxXWRvQ0+pffkrBxHLnPpxwi8= github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4= diff --git a/services/omnirpc/go.mod b/services/omnirpc/go.mod index 9602835ae4..0bc01d8863 100644 --- a/services/omnirpc/go.mod +++ b/services/omnirpc/go.mod @@ -192,6 +192,7 @@ require ( github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/prometheus/tsdb v0.10.0 // indirect + github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/pyroscope-io/client v0.7.2 // indirect github.com/pyroscope-io/godeltaprof v0.1.2 // indirect github.com/pyroscope-io/otel-profiling-go v0.4.0 // indirect diff --git a/services/omnirpc/go.sum b/services/omnirpc/go.sum index 665d7a3b1b..e9cff36b12 100644 --- a/services/omnirpc/go.sum +++ b/services/omnirpc/go.sum @@ -951,6 +951,8 @@ github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38i github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/puzpuzpuz/xsync v1.4.3 h1:nS/Iqc4EnpJ8jm/MzJ+e3MUaP2Ys2mqXeEfoxoU0HaM= github.com/puzpuzpuz/xsync v1.4.3/go.mod h1:K98BYhX3k1dQ2M63t1YNVDanbwUPmBCAhNmVrrxfiGg= +github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= +github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/pyroscope-io/client v0.7.2 h1:OX2qdUQsS8RSkn/3C8isD7f/P0YiZQlRbAlecAaj/R8= github.com/pyroscope-io/client v0.7.2/go.mod h1:FEocnjn+Ngzxy6EtU9ZxXWRvQ0+pffkrBxHLnPpxwi8= github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4=