From eb4d436f042e4bdcff413f5a62c6bdcb28293c27 Mon Sep 17 00:00:00 2001 From: James Walker Date: Mon, 26 Feb 2024 15:48:07 -0500 Subject: [PATCH 1/9] add CreateTransaction initial logic --- common/txmgr/inmemory_store.go | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/common/txmgr/inmemory_store.go b/common/txmgr/inmemory_store.go index c57c295cb82..34d316adefd 100644 --- a/common/txmgr/inmemory_store.go +++ b/common/txmgr/inmemory_store.go @@ -102,7 +102,30 @@ func (ms *InMemoryStore[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Creat txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error, ) { - return txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]{}, nil + if ms.chainID.String() != chainID.String() { + return tx, fmt.Errorf("create_transaction: %w", ErrInvalidChainID) + } + + ms.addressStatesLock.RLock() + defer ms.addressStatesLock.RUnlock() + as, ok := ms.addressStates[txRequest.FromAddress] + if !ok { + return tx, fmt.Errorf("create_transaction: %w", ErrAddressNotFound) + } + + // Persist Transaction to persistent storage + tx, err = ms.txStore.CreateTransaction(ctx, txRequest, chainID) + if err != nil { + return tx, fmt.Errorf("create_transaction: %w", err) + } + + // Update in memory store + // Add the request to the Unstarted channel to be processed by the Broadcaster + if err := as.AddTxToUnstarted(&tx); err != nil { + return *ms.deepCopyTx(tx), fmt.Errorf("create_transaction: %w", err) + } + + return *ms.deepCopyTx(tx), nil } // FindTxWithIdempotencyKey returns a transaction with the given idempotency key From 154d51473f706262580962fc1fa9b0be1f4e0d8d Mon Sep 17 00:00:00 2001 From: James Walker Date: Mon, 26 Feb 2024 16:34:09 -0500 Subject: [PATCH 2/9] cleanup --- common/txmgr/inmemory_store.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/txmgr/inmemory_store.go b/common/txmgr/inmemory_store.go index 2dd69894911..2c4cf5bb19c 100644 --- a/common/txmgr/inmemory_store.go +++ b/common/txmgr/inmemory_store.go @@ -103,6 +103,7 @@ func (ms *InMemoryStore[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Creat txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error, ) { + tx := txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]{} if ms.chainID.String() != chainID.String() { return tx, fmt.Errorf("create_transaction: %w", ErrInvalidChainID) } @@ -115,14 +116,14 @@ func (ms *InMemoryStore[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Creat } // Persist Transaction to persistent storage - tx, err = ms.txStore.CreateTransaction(ctx, txRequest, chainID) + tx, err := ms.txStore.CreateTransaction(ctx, txRequest, chainID) if err != nil { return tx, fmt.Errorf("create_transaction: %w", err) } // Update in memory store // Add the request to the Unstarted channel to be processed by the Broadcaster - if err := as.AddTxToUnstarted(&tx); err != nil { + if err := as.AddTxToUnstartedQueue(&tx); err != nil { return *ms.deepCopyTx(tx), fmt.Errorf("create_transaction: %w", err) } From 362dbe1b1434951c42ead5fd52ce65ae5105c505 Mon Sep 17 00:00:00 2001 From: James Walker Date: Mon, 26 Feb 2024 16:53:44 -0500 Subject: [PATCH 3/9] add tests for create transaction --- .../evm/txmgr/evm_inmemory_store_test.go | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 core/chains/evm/txmgr/evm_inmemory_store_test.go diff --git a/core/chains/evm/txmgr/evm_inmemory_store_test.go b/core/chains/evm/txmgr/evm_inmemory_store_test.go new file mode 100644 index 00000000000..9d51447f979 --- /dev/null +++ b/core/chains/evm/txmgr/evm_inmemory_store_test.go @@ -0,0 +1,89 @@ +package txmgr_test + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + commontxmgr "github.com/smartcontractkit/chainlink/v2/common/txmgr" + evmassets "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + evmgas "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + evmtxmgr "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" +) + +func TestInMemoryStore_CreateTransaction(t *testing.T) { + t.Parallel() + + db := pgtest.NewSqlxDB(t) + cfg := configtest.NewGeneralConfig(t, nil) + persistentStore := cltest.NewTestTxStore(t, db, cfg.Database()) + kst := cltest.NewKeyStore(t, db, cfg.Database()) + + _, fromAddress := cltest.MustInsertRandomKey(t, kst.Eth()) + toAddress := testutils.NewAddress() + gasLimit := uint32(1000) + payload := []byte{1, 2, 3} + + ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + lggr := logger.TestSugared(t) + chainID := ethClient.ConfiguredChainID() + ctx := context.Background() + + inMemoryStore, err := commontxmgr.NewInMemoryStore[ + *big.Int, + common.Address, common.Hash, common.Hash, + *evmtypes.Receipt, + evmtypes.Nonce, + evmgas.EvmFee, + ](ctx, lggr, chainID, kst.Eth(), persistentStore) + require.NoError(t, err) + + t.Run("with queue under capacity inserts eth_tx", func(t *testing.T) { + subject := uuid.New() + strategy := newMockTxStrategy(t) + strategy.On("Subject").Return(uuid.NullUUID{UUID: subject, Valid: true}) + actTx, err := inMemoryStore.CreateTransaction(testutils.Context(t), evmtxmgr.TxRequest{ + FromAddress: fromAddress, + ToAddress: toAddress, + EncodedPayload: payload, + FeeLimit: gasLimit, + Meta: nil, + Strategy: strategy, + }, chainID) + require.NoError(t, err) + + assert.Greater(t, actTx.ID, int64(0)) + assert.Equal(t, commontxmgr.TxUnstarted, actTx.State) + assert.Equal(t, gasLimit, actTx.FeeLimit) + assert.Equal(t, fromAddress, actTx.FromAddress) + assert.Equal(t, toAddress, actTx.ToAddress) + assert.Equal(t, payload, actTx.EncodedPayload) + assert.Equal(t, big.Int(evmassets.NewEthValue(0)), actTx.Value) + assert.Equal(t, subject, actTx.Subject.UUID) + + cltest.AssertCount(t, db, "evm.txes", 1) + + var dbEthTx evmtxmgr.DbEthTx + require.NoError(t, db.Get(&dbEthTx, `SELECT * FROM evm.txes ORDER BY id ASC LIMIT 1`)) + + assert.Equal(t, commontxmgr.TxUnstarted, dbEthTx.State) + assert.Equal(t, gasLimit, dbEthTx.GasLimit) + assert.Equal(t, fromAddress, dbEthTx.FromAddress) + assert.Equal(t, toAddress, dbEthTx.ToAddress) + assert.Equal(t, payload, dbEthTx.EncodedPayload) + assert.Equal(t, evmassets.NewEthValue(0), dbEthTx.Value) + assert.Equal(t, subject, dbEthTx.Subject.UUID) + }) +} From ddf02a3c1d0cbb1b31889b471867bd581dd01675 Mon Sep 17 00:00:00 2001 From: James Walker Date: Tue, 27 Feb 2024 15:56:20 -0500 Subject: [PATCH 4/9] add panic if incorrect ChainID --- common/txmgr/inmemory_store.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/txmgr/inmemory_store.go b/common/txmgr/inmemory_store.go index 2c4cf5bb19c..8ddf3a23f0d 100644 --- a/common/txmgr/inmemory_store.go +++ b/common/txmgr/inmemory_store.go @@ -105,7 +105,7 @@ func (ms *InMemoryStore[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Creat ) { tx := txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]{} if ms.chainID.String() != chainID.String() { - return tx, fmt.Errorf("create_transaction: %w", ErrInvalidChainID) + panic(fmt.Sprintf("create_transaction: invalid chain ID: %s", chainID)) } ms.addressStatesLock.RLock() From 25775387406b3cbae0e16526edb7cfd9d6e2eee7 Mon Sep 17 00:00:00 2001 From: James Walker Date: Mon, 11 Mar 2024 10:25:26 -0400 Subject: [PATCH 5/9] clean up test for CreateTransaction --- common/txmgr/inmemory_store.go | 10 ++++--- .../evm/txmgr/evm_inmemory_store_test.go | 29 +++++++------------ 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/common/txmgr/inmemory_store.go b/common/txmgr/inmemory_store.go index 8d6a73777ee..f41b97954ad 100644 --- a/common/txmgr/inmemory_store.go +++ b/common/txmgr/inmemory_store.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "math/big" + "sync" "time" "github.com/google/uuid" @@ -46,7 +47,8 @@ type inMemoryStore[ keyStore txmgrtypes.KeyStore[ADDR, CHAIN_ID, SEQ] persistentTxStore txmgrtypes.TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] - addressStates map[ADDR]*addressState[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE] + addressStatesLock sync.RWMutex + addressStates map[ADDR]*addressState[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE] } // NewInMemoryStore returns a new inMemoryStore @@ -107,18 +109,18 @@ func (ms *inMemoryStore[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Creat defer ms.addressStatesLock.RUnlock() as, ok := ms.addressStates[txRequest.FromAddress] if !ok { - return tx, fmt.Errorf("create_transaction: %w", ErrAddressNotFound) + return tx, fmt.Errorf("create_transaction: %w: %q", ErrAddressNotFound, txRequest.FromAddress) } // Persist Transaction to persistent storage - tx, err := ms.txStore.CreateTransaction(ctx, txRequest, chainID) + tx, err := ms.persistentTxStore.CreateTransaction(ctx, txRequest, chainID) if err != nil { return tx, fmt.Errorf("create_transaction: %w", err) } // Update in memory store // Add the request to the Unstarted channel to be processed by the Broadcaster - if err := as.AddTxToUnstartedQueue(&tx); err != nil { + if err := as.addTxToUnstartedQueue(&tx); err != nil { return *ms.deepCopyTx(tx), fmt.Errorf("create_transaction: %w", err) } diff --git a/core/chains/evm/txmgr/evm_inmemory_store_test.go b/core/chains/evm/txmgr/evm_inmemory_store_test.go index 6ae06e99414..4f53a51bf09 100644 --- a/core/chains/evm/txmgr/evm_inmemory_store_test.go +++ b/core/chains/evm/txmgr/evm_inmemory_store_test.go @@ -18,7 +18,6 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" ) @@ -27,14 +26,10 @@ func TestInMemoryStore_CreateTransaction(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - cfg := configtest.NewGeneralConfig(t, nil) - persistentStore := cltest.NewTestTxStore(t, db, cfg.Database()) - kst := cltest.NewKeyStore(t, db, cfg.Database()) - + _, dbcfg, evmcfg := evmtxmgr.MakeTestConfigs(t) + persistentStore := cltest.NewTestTxStore(t, db, dbcfg) + kst := cltest.NewKeyStore(t, db, dbcfg) _, fromAddress := cltest.MustInsertRandomKey(t, kst.Eth()) - toAddress := testutils.NewAddress() - gasLimit := uint32(1000) - payload := []byte{1, 2, 3} ethClient := evmtest.NewEthClientMockWithDefaultChain(t) lggr := logger.TestSugared(t) @@ -47,9 +42,13 @@ func TestInMemoryStore_CreateTransaction(t *testing.T) { *evmtypes.Receipt, evmtypes.Nonce, evmgas.EvmFee, - ](ctx, lggr, chainID, kst.Eth(), persistentStore) + ](ctx, lggr, chainID, kst.Eth(), persistentStore, evmcfg.Transactions()) require.NoError(t, err) + toAddress := testutils.NewAddress() + gasLimit := uint32(1000) + payload := []byte{1, 2, 3} + t.Run("with queue under capacity inserts eth_tx", func(t *testing.T) { subject := uuid.New() strategy := newMockTxStrategy(t) @@ -64,15 +63,7 @@ func TestInMemoryStore_CreateTransaction(t *testing.T) { }, chainID) require.NoError(t, err) - assert.Greater(t, actTx.ID, int64(0)) - assert.Equal(t, commontxmgr.TxUnstarted, actTx.State) - assert.Equal(t, gasLimit, actTx.FeeLimit) - assert.Equal(t, fromAddress, actTx.FromAddress) - assert.Equal(t, toAddress, actTx.ToAddress) - assert.Equal(t, payload, actTx.EncodedPayload) - assert.Equal(t, big.Int(evmassets.NewEthValue(0)), actTx.Value) - assert.Equal(t, subject, actTx.Subject.UUID) - + // check that the transaction was inserted into the persistent store cltest.AssertCount(t, db, "evm.txes", 1) var dbEthTx evmtxmgr.DbEthTx @@ -88,6 +79,8 @@ func TestInMemoryStore_CreateTransaction(t *testing.T) { var expTx evmtxmgr.Tx dbEthTx.ToTx(&expTx) + + // check that the in-memory store has the same transaction data as the persistent store assertTxEqual(t, expTx, actTx) }) } From b470da7194cc82a2ca6df88dcb1c1f655aa99bbb Mon Sep 17 00:00:00 2001 From: James Walker Date: Wed, 20 Mar 2024 23:18:59 -0400 Subject: [PATCH 6/9] address comments --- common/txmgr/inmemory_store.go | 13 +++++++------ core/chains/evm/txmgr/evm_inmemory_store_test.go | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/common/txmgr/inmemory_store.go b/common/txmgr/inmemory_store.go index 8eaca33c49f..a380e40ba8a 100644 --- a/common/txmgr/inmemory_store.go +++ b/common/txmgr/inmemory_store.go @@ -46,6 +46,7 @@ type inMemoryStore[ keyStore txmgrtypes.KeyStore[ADDR, CHAIN_ID, SEQ] persistentTxStore txmgrtypes.TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE] + maxUnstarted uint64 addressStatesLock sync.RWMutex addressStates map[ADDR]*addressState[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE] @@ -75,9 +76,9 @@ func NewInMemoryStore[ addressStates: map[ADDR]*addressState[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]{}, } - maxUnstarted := config.MaxQueued() - if maxUnstarted <= 0 { - maxUnstarted = 10000 + ms.maxUnstarted = config.MaxQueued() + if ms.maxUnstarted <= 0 { + ms.maxUnstarted = 10000 } addresses, err := keyStore.EnabledAddressesForChain(ctx, chainID) if err != nil { @@ -88,7 +89,7 @@ func NewInMemoryStore[ if err != nil { return nil, fmt.Errorf("address_state: initialization: %w", err) } - ms.addressStates[fromAddr] = newAddressState[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE](lggr, chainID, fromAddr, maxUnstarted, txs) + ms.addressStates[fromAddr] = newAddressState[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE](lggr, chainID, fromAddr, ms.maxUnstarted, txs) } return &ms, nil @@ -105,14 +106,14 @@ func (ms *inMemoryStore[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Creat ) { tx := txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]{} if ms.chainID.String() != chainID.String() { - panic(fmt.Sprintf("create_transaction: invalid chain ID: %s", chainID)) + panic(fmt.Sprintf(ErrInvalidChainID.Error()+": %s", chainID.String())) } ms.addressStatesLock.RLock() defer ms.addressStatesLock.RUnlock() as, ok := ms.addressStates[txRequest.FromAddress] if !ok { - return tx, fmt.Errorf("create_transaction: %w: %q", ErrAddressNotFound, txRequest.FromAddress) + as = newAddressState[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE](ms.lggr, chainID, txRequest.FromAddress, ms.maxUnstarted, nil) } // Persist Transaction to persistent storage diff --git a/core/chains/evm/txmgr/evm_inmemory_store_test.go b/core/chains/evm/txmgr/evm_inmemory_store_test.go index 4f53a51bf09..9b280519c67 100644 --- a/core/chains/evm/txmgr/evm_inmemory_store_test.go +++ b/core/chains/evm/txmgr/evm_inmemory_store_test.go @@ -57,7 +57,7 @@ func TestInMemoryStore_CreateTransaction(t *testing.T) { FromAddress: fromAddress, ToAddress: toAddress, EncodedPayload: payload, - FeeLimit: gasLimit, + FeeLimit: uint64(gasLimit), Meta: nil, Strategy: strategy, }, chainID) From 395d35fe005c96ffb01b9962dadd14340689b11b Mon Sep 17 00:00:00 2001 From: James Walker Date: Thu, 21 Mar 2024 14:49:22 -0400 Subject: [PATCH 7/9] fix address state issue if from address not available --- common/txmgr/inmemory_store.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/txmgr/inmemory_store.go b/common/txmgr/inmemory_store.go index a380e40ba8a..d2af7415bfd 100644 --- a/common/txmgr/inmemory_store.go +++ b/common/txmgr/inmemory_store.go @@ -109,11 +109,12 @@ func (ms *inMemoryStore[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Creat panic(fmt.Sprintf(ErrInvalidChainID.Error()+": %s", chainID.String())) } - ms.addressStatesLock.RLock() - defer ms.addressStatesLock.RUnlock() + ms.addressStatesLock.Lock() + defer ms.addressStatesLock.Unlock() as, ok := ms.addressStates[txRequest.FromAddress] if !ok { as = newAddressState[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE](ms.lggr, chainID, txRequest.FromAddress, ms.maxUnstarted, nil) + ms.addressStates[txRequest.FromAddress] = as } // Persist Transaction to persistent storage From f7eb968f1013515ebfee043b62bb36af58f5d7d2 Mon Sep 17 00:00:00 2001 From: James Walker Date: Thu, 21 Mar 2024 15:36:20 -0400 Subject: [PATCH 8/9] address comments --- core/chains/evm/txmgr/evm_inmemory_store_test.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/chains/evm/txmgr/evm_inmemory_store_test.go b/core/chains/evm/txmgr/evm_inmemory_store_test.go index 9b280519c67..07ce523cb3f 100644 --- a/core/chains/evm/txmgr/evm_inmemory_store_test.go +++ b/core/chains/evm/txmgr/evm_inmemory_store_test.go @@ -1,7 +1,6 @@ package txmgr_test import ( - "context" "math/big" "testing" @@ -27,14 +26,14 @@ func TestInMemoryStore_CreateTransaction(t *testing.T) { db := pgtest.NewSqlxDB(t) _, dbcfg, evmcfg := evmtxmgr.MakeTestConfigs(t) - persistentStore := cltest.NewTestTxStore(t, db, dbcfg) + persistentStore := cltest.NewTestTxStore(t, db) kst := cltest.NewKeyStore(t, db, dbcfg) _, fromAddress := cltest.MustInsertRandomKey(t, kst.Eth()) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) lggr := logger.TestSugared(t) chainID := ethClient.ConfiguredChainID() - ctx := context.Background() + ctx := testutils.Context(t) inMemoryStore, err := commontxmgr.NewInMemoryStore[ *big.Int, @@ -53,7 +52,7 @@ func TestInMemoryStore_CreateTransaction(t *testing.T) { subject := uuid.New() strategy := newMockTxStrategy(t) strategy.On("Subject").Return(uuid.NullUUID{UUID: subject, Valid: true}) - actTx, err := inMemoryStore.CreateTransaction(testutils.Context(t), evmtxmgr.TxRequest{ + actTx, err := inMemoryStore.CreateTransaction(ctx, evmtxmgr.TxRequest{ FromAddress: fromAddress, ToAddress: toAddress, EncodedPayload: payload, From bffcc71024bcc69a8be4427b04730efe9c6ed5b4 Mon Sep 17 00:00:00 2001 From: James Walker Date: Mon, 1 Apr 2024 13:59:57 -0400 Subject: [PATCH 9/9] clean up --- common/txmgr/inmemory_store.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/common/txmgr/inmemory_store.go b/common/txmgr/inmemory_store.go index 63afb61e25a..3c8eb97b18d 100644 --- a/common/txmgr/inmemory_store.go +++ b/common/txmgr/inmemory_store.go @@ -112,16 +112,16 @@ func (ms *inMemoryStore[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Creat ) { tx := txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]{} if ms.chainID.String() != chainID.String() { - panic(fmt.Sprintf(ErrInvalidChainID.Error()+": %s", chainID.String())) + panic("invalid chain ID") } ms.addressStatesLock.Lock() - defer ms.addressStatesLock.Unlock() as, ok := ms.addressStates[txRequest.FromAddress] if !ok { as = newAddressState[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE](ms.lggr, chainID, txRequest.FromAddress, ms.maxUnstarted, nil) ms.addressStates[txRequest.FromAddress] = as } + ms.addressStatesLock.Unlock() // Persist Transaction to persistent storage tx, err := ms.persistentTxStore.CreateTransaction(ctx, txRequest, chainID) @@ -132,7 +132,6 @@ func (ms *inMemoryStore[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Creat // Update in memory store // Add the request to the Unstarted channel to be processed by the Broadcaster as.addTxToUnstartedQueue(&tx) - return *ms.deepCopyTx(tx), nil }