github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/modules/blockchain/tx.go (about) 1 package blockchain 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/ethereum/go-ethereum" 8 "github.com/ethereum/go-ethereum/common" 9 "github.com/pkg/errors" 10 11 "github.com/machinefi/w3bstream/pkg/depends/conf/logger" 12 "github.com/machinefi/w3bstream/pkg/depends/kit/logr" 13 "github.com/machinefi/w3bstream/pkg/depends/kit/sqlx/builder" 14 "github.com/machinefi/w3bstream/pkg/depends/kit/sqlx/datatypes" 15 "github.com/machinefi/w3bstream/pkg/models" 16 "github.com/machinefi/w3bstream/pkg/types" 17 ) 18 19 type tx struct { 20 *monitor 21 interval time.Duration 22 } 23 24 func (t *tx) run(ctx context.Context) { 25 ticker := time.NewTicker(t.interval) 26 defer ticker.Stop() 27 28 for range ticker.C { 29 t.do(ctx) 30 } 31 } 32 33 func (t *tx) do(ctx context.Context) { 34 ctx, l := logger.NewSpanContext(ctx, "bc.tx.do") 35 defer l.End() 36 37 d := types.MustMonitorDBExecutorFromContext(ctx) 38 m := &models.ChainTx{} 39 40 cs, err := m.List(d, builder.And(m.ColFinished().Eq(datatypes.FALSE), m.ColPaused().Eq(datatypes.FALSE))) 41 if err != nil { 42 l.Error(errors.Wrap(err, "list chain tx db failed")) 43 return 44 } 45 for _, c := range cs { 46 res, err := t.checkTxAndSendEvent(ctx, &c) 47 if err != nil { 48 l.Error(errors.Wrap(err, "check chain tx and send event failed")) 49 continue 50 } 51 if res { 52 c.Finished = datatypes.TRUE 53 c.Uniq = c.ChainTxID 54 if err := c.UpdateByID(d); err != nil { 55 l.Error(errors.Wrap(err, "update chain tx db failed")) 56 } 57 } 58 } 59 60 } 61 62 func (t *tx) checkTxAndSendEvent(ctx context.Context, c *models.ChainTx) (bool, error) { 63 ctx, l := logr.Start(ctx, "bc.tx.checkTxAndSendEvent") 64 defer l.End() 65 66 l = l.WithValues("type", "chain_tx", "chain_tx_id", c.ChainTxID) 67 68 ethclients := types.MustETHClientConfigFromContext(ctx) 69 70 cli, ok := ethclients.Clients[uint32(c.ChainID)] 71 if !ok { 72 return false, errors.Errorf("chain id is not exist: %d", c.ChainID) 73 } 74 75 txhash, ispending, err := cli.TransactionByHash(context.Background(), common.HexToHash(c.TxAddress)) 76 if err != nil { 77 if err == ethereum.NotFound { 78 l.WithValues("tx_hash", c.TxAddress).Debug("transaction not found") 79 return false, nil 80 } 81 l.Error(err) 82 return false, err 83 } 84 if ispending { 85 l.WithValues("tx_hash", c.TxAddress).Debug("transaction pending") 86 return false, nil 87 } 88 data, err := txhash.MarshalJSON() 89 if err != nil { 90 l.Error(err) 91 return false, err 92 } 93 if err := t.sendEvent(ctx, data, c.ProjectName, c.EventType); err != nil { 94 l.Error(err) 95 return false, err 96 } 97 return true, nil 98 }