Skip to content
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
4 changes: 2 additions & 2 deletions tools/preconf-rpc/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -604,10 +604,10 @@ func (h *rpcMethodHandler) handleGetTxReceipt(ctx context.Context, params ...any
}

switch txn.Status {
case sender.TxStatusPending, sender.TxStatusConfirmed:
case sender.TxStatusPending, sender.TxStatusConfirmed, sender.TxStatusFailed:
// go to RPC proxy
return nil, true, nil
case sender.TxStatusPreConfirmed, sender.TxStatusFailed:
case sender.TxStatusPreConfirmed:
// continue processing
}

Expand Down
18 changes: 0 additions & 18 deletions tools/preconf-rpc/sender/sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,24 +580,6 @@ func (t *TxSender) processQueuedTransactions(ctx context.Context) {
txn.Status = TxStatusFailed
txn.Details = err.Error()
t.clearBlockAttemptHistory(txn, time.Now())

// Store a failed receipt to unblock the user's wallet
receipt := &types.Receipt{
Type: txn.Transaction.Type(),
Status: types.ReceiptStatusFailed,
TxHash: txn.Hash(),
ContractAddress: common.Address{},
GasUsed: 21000,
CumulativeGasUsed: 21000,
BlockHash: common.BytesToHash(big.NewInt(int64(t.blockTracker.LatestBlockNumber())).Bytes()),
BlockNumber: big.NewInt(int64(t.blockTracker.LatestBlockNumber())),
TransactionIndex: 0,
}
if storeErr := t.store.StoreReceipt(ctx, receipt); storeErr != nil {
t.logger.Error("Failed to store failed receipt", "error", storeErr)
}

defer t.signalReceiptAvailable(txn.Hash())
return t.store.StoreTransaction(ctx, txn, nil, nil)
}
return nil
Expand Down
11 changes: 10 additions & 1 deletion tools/preconf-rpc/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,16 @@ func (s *rpcstore) AddQueuedTransaction(ctx context.Context, tx *sender.Transact
}
insertQuery := `
INSERT INTO mcTransactions (hash, nonce, raw_transaction, sender, tx_type, status, options)
VALUES ($1, $2, $3, $4, $5, $6, $7);
VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT (hash) DO UPDATE
SET status = EXCLUDED.status,
nonce = EXCLUDED.nonce,
sender = EXCLUDED.sender,
tx_type = EXCLUDED.tx_type,
options = EXCLUDED.options,
details = EXCLUDED.details,
raw_transaction = EXCLUDED.raw_transaction
WHERE mcTransactions.status != 'confirmed' AND mcTransactions.status != 'pre-confirmed';
`
_, err = s.db.ExecContext(
ctx,
Expand Down
37 changes: 35 additions & 2 deletions tools/preconf-rpc/store/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,42 @@ func TestStore(t *testing.T) {
}

err = st.AddQueuedTransaction(context.Background(), wrappedTxn1) // Adding the same transaction again
if err == nil {
t.Fatalf("expected error when adding duplicate transaction, got nil")
if err != nil {
t.Fatalf("expected nil error when adding duplicate transaction, got %v", err)
}

// Test retry of failed transaction:
// 1. Manually set txn1 to failed in DB
wrappedTxn1.Status = sender.TxStatusFailed
wrappedTxn1.Details = "failed simulation"
// We use StoreTransaction to update the status in DB
if err := st.StoreTransaction(context.Background(), wrappedTxn1, nil, nil); err != nil {
t.Fatalf("failed to update transaction to failed: %v", err)
}

// 2. Retry: AddQueuedTransaction should reset status to Pending
wrappedTxn1Retry := &sender.Transaction{
Transaction: wrappedTxn1.Transaction,
Raw: wrappedTxn1.Raw,
Sender: wrappedTxn1.Sender,
Type: wrappedTxn1.Type,
Status: sender.TxStatusPending,
}
if err := st.AddQueuedTransaction(context.Background(), wrappedTxn1Retry); err != nil {
t.Fatalf("failed to re-queue failed transaction: %v", err)
}

// 3. Verify status is Pending
retrievedTxn1, err := st.GetTransactionByHash(context.Background(), wrappedTxn1.Hash())
if err != nil {
t.Fatalf("failed to retrieve retried transaction: %v", err)
}
if retrievedTxn1.Status != sender.TxStatusPending {
t.Fatalf("expected status to be pending after retry, got %s", retrievedTxn1.Status)
}
// Restore wrappedTxn1 status for subsequent tests
wrappedTxn1.Status = sender.TxStatusPending
wrappedTxn1.Details = ""

err = st.AddQueuedTransaction(context.Background(), wrappedTxn2)
if err != nil {
Expand Down
Loading