github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/modules/blockchain/monitor.go (about)

     1  package blockchain
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	"github.com/pkg/errors"
     8  
     9  	"github.com/machinefi/w3bstream/pkg/depends/kit/logr"
    10  	"github.com/machinefi/w3bstream/pkg/depends/kit/sqlx/builder"
    11  	"github.com/machinefi/w3bstream/pkg/errors/status"
    12  	"github.com/machinefi/w3bstream/pkg/models"
    13  	"github.com/machinefi/w3bstream/pkg/modules/event"
    14  	"github.com/machinefi/w3bstream/pkg/types"
    15  )
    16  
    17  // TODO move to config
    18  const (
    19  	listInterval  = 3 * time.Second
    20  	blockInterval = 4000
    21  )
    22  
    23  func InitChainDB(ctx context.Context) error {
    24  	d := types.MustMonitorDBExecutorFromContext(ctx)
    25  
    26  	m := &models.Blockchain{
    27  		RelBlockchain:  models.RelBlockchain{ChainID: 4690},
    28  		BlockchainInfo: models.BlockchainInfo{Address: "https://babel-api.testnet.iotex.io"},
    29  	}
    30  
    31  	results := make([]models.Account, 0)
    32  	err := d.QueryAndScan(builder.Select(nil).
    33  		From(
    34  			d.T(m),
    35  			builder.Where(
    36  				builder.And(
    37  					m.ColChainID().Eq(4690),
    38  				),
    39  			),
    40  		), &results)
    41  	if err != nil {
    42  		return status.DatabaseError.StatusErr().
    43  			WithDesc(errors.Wrap(err, "FetchChain").Error())
    44  	}
    45  	if len(results) > 0 {
    46  		return nil
    47  	}
    48  	return m.Create(d)
    49  }
    50  
    51  func Monitor(ctx context.Context) {
    52  	m := &monitor{}
    53  	c := &contract{
    54  		monitor:       m,
    55  		listInterval:  listInterval,
    56  		blockInterval: blockInterval,
    57  	}
    58  	h := &height{
    59  		monitor:  m,
    60  		interval: listInterval,
    61  	}
    62  	t := &tx{
    63  		monitor:  m,
    64  		interval: listInterval,
    65  	}
    66  	go c.run(ctx)
    67  	go h.run(ctx)
    68  	go t.run(ctx)
    69  }
    70  
    71  type monitor struct{}
    72  
    73  func (*monitor) sendEvent(ctx context.Context, data []byte, projectName string, eventType string) error {
    74  	ctx, l := logr.Start(ctx, "bc.monitor.sendEvent", "prj", projectName, "event_type", eventType)
    75  	defer l.End()
    76  
    77  	// COMMENT: this should be a rpc, projectName is enough? TODO @zhiran
    78  	ctx = types.WithProject(ctx, &models.Project{
    79  		ProjectName: models.ProjectName{Name: projectName}},
    80  	)
    81  	ret, err := event.SyncHandleEvent(ctx, eventType, data)
    82  	if err != nil {
    83  		l.Error(err)
    84  		return err
    85  	}
    86  	for _, r := range ret.Results {
    87  		if r.Error != "" {
    88  			err = errors.New(r.Error)
    89  			l.Error(err)
    90  			return err
    91  		}
    92  	}
    93  	return nil
    94  }