@@ -19,6 +19,7 @@ package eth
19
19
import (
20
20
"context"
21
21
"errors"
22
+ "github.com/ethereum/go-ethereum/log"
22
23
"math/big"
23
24
"time"
24
25
@@ -274,18 +275,23 @@ func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscri
274
275
func (b * EthAPIBackend ) SendTx (ctx context.Context , signedTx * types.Transaction ) error {
275
276
locals := b .eth .localTxTracker
276
277
if locals != nil {
278
+ // If tx tracker already has the tx, that indicates
279
+ // the transaction has been submitted once.
280
+ // So local tracker should make sure the transaction
281
+ // submitted in the end. Just return nil error to inform
282
+ // the rpc client that tx has been received.
283
+ if locals .HasTx (signedTx .Hash ()) {
284
+ log .Trace ("Tx tracker has transaction and no need to add it to tx-pool" , "hash" , signedTx .Hash ().Hex ())
285
+ return nil
286
+ }
287
+ // Transaction won't be tracked if tracker already has it
277
288
if err := locals .Track (signedTx ); err != nil {
278
289
return err
279
290
}
280
291
}
281
- // No error will be returned to user if the transaction fails stateful
282
- // validation (e.g., no available slot), as the locally submitted transactions
283
- // may be resubmitted later via the local tracker.
284
- err := b .eth .txPool .Add ([]* types.Transaction {signedTx }, false )[0 ]
285
- if err != nil && locals == nil {
286
- return err
287
- }
288
- return nil
292
+ // The rpc client needs to be informed if there is
293
+ // stateful validation problems.
294
+ return b .eth .txPool .Add ([]* types.Transaction {signedTx }, false )[0 ]
289
295
}
290
296
291
297
func (b * EthAPIBackend ) GetPoolTransactions () (types.Transactions , error ) {
0 commit comments