Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TXM In-memory: step 3-02-CreateTransaction #12181

Merged
merged 15 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion common/txmgr/inmemory_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,29 @@ 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
tx := txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]{}
if ms.chainID.String() != chainID.String() {
panic("invalid chain ID")
Copy link
Contributor

@DylanTinianov DylanTinianov Apr 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Might be useful to improve these error messages across all functions in case the panic occurs. Something like the following?

Suggested change
panic("invalid chain ID")
panic(fmt.Sprintf("invalid chain ID: expected %s but recieved %s", ms.chainID.String(), chainID.String())

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linked this in #12176 so we can address it to the other panics as well

}

ms.addressStatesLock.Lock()
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)
poopoothegorilla marked this conversation as resolved.
Show resolved Hide resolved
ms.addressStates[txRequest.FromAddress] = as
}
ms.addressStatesLock.Unlock()

// Persist Transaction to persistent storage
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
as.addTxToUnstartedQueue(&tx)
return *ms.deepCopyTx(tx), nil
}

// FindTxWithIdempotencyKey returns a transaction with the given idempotency key
Expand Down
64 changes: 64 additions & 0 deletions core/chains/evm/txmgr/evm_inmemory_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
commontxmgr "github.com/smartcontractkit/chainlink/v2/common/txmgr"
txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types"

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"
Expand All @@ -23,6 +24,69 @@
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
)

func TestInMemoryStore_CreateTransaction(t *testing.T) {
t.Parallel()

db := pgtest.NewSqlxDB(t)
_, dbcfg, evmcfg := evmtxmgr.MakeTestConfigs(t)
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 := testutils.Context(t)

inMemoryStore, err := commontxmgr.NewInMemoryStore[
*big.Int,
common.Address, common.Hash, common.Hash,
*evmtypes.Receipt,
evmtypes.Nonce,
evmgas.EvmFee,
](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)
strategy.On("Subject").Return(uuid.NullUUID{UUID: subject, Valid: true})
actTx, err := inMemoryStore.CreateTransaction(ctx, evmtxmgr.TxRequest{
FromAddress: fromAddress,
ToAddress: toAddress,
EncodedPayload: payload,
FeeLimit: uint64(gasLimit),
Meta: nil,
Strategy: strategy,
}, chainID)
require.NoError(t, err)

// check that the transaction was inserted into the persistent store
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)

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)
})
}

func TestInMemoryStore_PruneUnstartedTxQueue(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -50,7 +114,7 @@
maxQueueSize := uint32(5)
nTxs := 3
subject := uuid.NullUUID{UUID: uuid.New(), Valid: true}
strat := commontxmgr.NewDropOldestStrategy(subject.UUID, maxQueueSize, dbcfg.DefaultQueryTimeout())

Check failure on line 117 in core/chains/evm/txmgr/evm_inmemory_store_test.go

View workflow job for this annotation

GitHub Actions / lint

`strat` is a misspelling of `start` (misspell)
for i := 0; i < nTxs; i++ {
inTx := cltest.NewEthTx(fromAddress)
inTx.Subject = subject
Expand Down Expand Up @@ -87,7 +151,7 @@
maxQueueSize := uint32(5)
nTxs := 5
subject := uuid.NullUUID{UUID: uuid.New(), Valid: true}
strat := commontxmgr.NewDropOldestStrategy(subject.UUID, maxQueueSize, dbcfg.DefaultQueryTimeout())

Check failure on line 154 in core/chains/evm/txmgr/evm_inmemory_store_test.go

View workflow job for this annotation

GitHub Actions / lint

`strat` is a misspelling of `start` (misspell)
for i := 0; i < nTxs; i++ {
inTx := cltest.NewEthTx(fromAddress)
inTx.Subject = subject
Expand All @@ -99,7 +163,7 @@

ids, err := strat.PruneQueue(ctx, inMemoryStore)
require.NoError(t, err)
assert.Equal(t, int(nTxs)-int(maxQueueSize-1), len(ids))

Check failure on line 166 in core/chains/evm/txmgr/evm_inmemory_store_test.go

View workflow job for this annotation

GitHub Actions / lint

unnecessary conversion (unconvert)

AssertCountPerSubject(t, persistentStore, int64(maxQueueSize-1), subject.UUID)
fn := func(tx *evmtxmgr.Tx) bool { return true }
Expand Down
Loading