Handling transactions with more than one instruction in solana watcher (#932)
Add redeem controller Co-authored-by: walker-16 <agpazos85@gmail.com>
This commit is contained in:
parent
d7391f6ba1
commit
bb5840f70f
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/builder"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/config"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/http/infrastructure"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/http/redeem"
|
||||
cwAlert "github.com/wormhole-foundation/wormhole-explorer/contract-watcher/internal/alert"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/internal/ankr"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/internal/metrics"
|
||||
|
@ -114,7 +115,8 @@ func Run() {
|
|||
processor.Start(rootCtx)
|
||||
|
||||
// create and start server.
|
||||
server := infrastructure.NewServer(logger, config.Port, config.PprofEnabled, healthChecks...)
|
||||
redeemController := redeem.NewController(watchers, logger)
|
||||
server := infrastructure.NewServer(logger, config.Port, config.PprofEnabled, redeemController, healthChecks...)
|
||||
server.Start()
|
||||
|
||||
logger.Info("Started wormhole-explorer-contract-watcher")
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/pprof"
|
||||
health "github.com/wormhole-foundation/wormhole-explorer/common/health"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/http/redeem"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -14,7 +15,7 @@ type Server struct {
|
|||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewServer(logger *zap.Logger, port string, pprofEnabled bool, checks ...health.Check) *Server {
|
||||
func NewServer(logger *zap.Logger, port string, pprofEnabled bool, redeemController *redeem.Controller, checks ...health.Check) *Server {
|
||||
app := fiber.New(fiber.Config{DisableStartupMessage: true})
|
||||
|
||||
// Configure middleware
|
||||
|
@ -32,6 +33,8 @@ func NewServer(logger *zap.Logger, port string, pprofEnabled bool, checks ...hea
|
|||
api.Get("/health", ctrl.HealthCheck)
|
||||
api.Get("/ready", ctrl.ReadyCheck)
|
||||
|
||||
api.Post("/backfill", redeemController.Backfill)
|
||||
|
||||
return &Server{
|
||||
app: app,
|
||||
port: port,
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package redeem
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/watcher"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Controller definition.
|
||||
type Controller struct {
|
||||
watcherByBlockchain map[string]watcher.ContractWatcher
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewController creates a Controller instance.
|
||||
func NewController(watckers []watcher.ContractWatcher, logger *zap.Logger) *Controller {
|
||||
watcherByBlockchain := make(map[string]watcher.ContractWatcher)
|
||||
for _, w := range watckers {
|
||||
watcherByBlockchain[w.GetBlockchain()] = w
|
||||
}
|
||||
return &Controller{watcherByBlockchain: watcherByBlockchain, logger: logger}
|
||||
}
|
||||
|
||||
func (c *Controller) Backfill(ctx *fiber.Ctx) error {
|
||||
payload := struct {
|
||||
Blockchain string `json:"blockchain"`
|
||||
FromBlock uint64 `json:"fromBlock"`
|
||||
ToBlock uint64 `json:"toBlock"`
|
||||
}{}
|
||||
|
||||
if err := ctx.BodyParser(&payload); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.logger.Info("Executing contract-watcher", zap.Any("payload", payload))
|
||||
|
||||
watcher, ok := c.watcherByBlockchain[payload.Blockchain]
|
||||
if !ok {
|
||||
return fiber.NewError(fiber.StatusNotFound, "Blockchain not found")
|
||||
}
|
||||
|
||||
watcher.Backfill(ctx.Context(), payload.FromBlock, payload.ToBlock, 100, false)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -62,6 +62,10 @@ func NewAptosWatcher(client *aptos.AptosSDK, params AptosParams, repo *storage.R
|
|||
}
|
||||
}
|
||||
|
||||
func (w *AptosWatcher) GetBlockchain() string {
|
||||
return w.blockchain
|
||||
}
|
||||
|
||||
func (w *AptosWatcher) Start(ctx context.Context) error {
|
||||
// get the current block for the chain.
|
||||
cBlock, err := w.repository.GetCurrentBlock(ctx, w.blockchain, w.initialBlock)
|
||||
|
|
|
@ -6,6 +6,7 @@ import "context"
|
|||
// It Tracks contract operations and persist the tx data
|
||||
// Backfill is used to backfill the contract data from the past
|
||||
type ContractWatcher interface {
|
||||
GetBlockchain() string
|
||||
Start(ctx context.Context) error
|
||||
Close()
|
||||
Backfill(ctx context.Context, fromBlock uint64, toBlock uint64, pageSize uint64, persistBlock bool)
|
||||
|
|
|
@ -56,6 +56,10 @@ func NewEvmStandardWatcher(client *evm.EvmSDK, params EVMParams, repo *storage.R
|
|||
}
|
||||
}
|
||||
|
||||
func (w *EvmStandardWatcher) GetBlockchain() string {
|
||||
return w.blockchain
|
||||
}
|
||||
|
||||
func (w *EvmStandardWatcher) Start(ctx context.Context) error {
|
||||
// get the current block for the chain.
|
||||
cBlock, err := w.repository.GetCurrentBlock(ctx, w.blockchain, w.initialBlock)
|
||||
|
|
|
@ -51,6 +51,10 @@ func NewEVMWatcher(client *ankr.AnkrSDK, repo *storage.Repository, params EVMPar
|
|||
}
|
||||
}
|
||||
|
||||
func (w *EVMWatcher) GetBlockchain() string {
|
||||
return w.blockchain
|
||||
}
|
||||
|
||||
func (w *EVMWatcher) Start(ctx context.Context) error {
|
||||
// get the current block for the chain.
|
||||
currentBlock, err := w.repository.GetCurrentBlock(ctx, w.blockchain, w.initialBlock)
|
||||
|
|
|
@ -115,6 +115,10 @@ func NewSolanaWatcher(client *solana.SolanaSDK, repo *storage.Repository, params
|
|||
}
|
||||
}
|
||||
|
||||
func (w *SolanaWatcher) GetBlockchain() string {
|
||||
return w.blockchain
|
||||
}
|
||||
|
||||
func (w *SolanaWatcher) Start(ctx context.Context) error {
|
||||
// get the current block for the chain.
|
||||
cBlock, err := w.repository.GetCurrentBlock(ctx, w.blockchain, w.initialBlock)
|
||||
|
@ -208,7 +212,6 @@ func (w *SolanaWatcher) processMultipleBlocks(ctx context.Context, fromBlock uin
|
|||
}
|
||||
w.repository.UpdateWatcherBlock(ctx, w.chainID, watcherBlock)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (w *SolanaWatcher) processBlock(ctx context.Context, block uint64, latestBlock *solana.GetLatestBlockResult, logger *zap.Logger) {
|
||||
|
@ -221,7 +224,7 @@ func (w *SolanaWatcher) processBlock(ctx context.Context, block uint64, latestBl
|
|||
result, err := w.client.GetBlock(ctx, block)
|
||||
if err != nil {
|
||||
if err == solana.ErrSlotSkipped {
|
||||
logger.Info("slot was skipped")
|
||||
logger.Debug("slot was skipped")
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("cannot get block. %w", err)
|
||||
|
@ -323,8 +326,7 @@ func (w *SolanaWatcher) processTransaction(ctx context.Context, txRpc *rpc.Trans
|
|||
log.Error("getting transaction detail failed", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
if len(t.Message.Instructions) == 1 {
|
||||
instruccion := t.Message.Instructions[0]
|
||||
for i, instruccion := range t.Message.Instructions {
|
||||
if len(instruccion.Data) == 0 {
|
||||
log.Debug("instruction data is empty")
|
||||
continue
|
||||
|
@ -337,7 +339,7 @@ func (w *SolanaWatcher) processTransaction(ctx context.Context, txRpc *rpc.Trans
|
|||
|
||||
var data postVAAData
|
||||
if err := borsh.Deserialize(&data, instruccion.Data[1:]); err != nil {
|
||||
log.Error("failed to deserialize instruction data", zap.Error(err))
|
||||
log.Error("failed to deserialize instruction data", zap.Error(err), zap.Int("index", i))
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -357,8 +359,8 @@ func (w *SolanaWatcher) processTransaction(ctx context.Context, txRpc *rpc.Trans
|
|||
|
||||
// update global transaction and check if it should be updated.
|
||||
updateGlobalTransaction(ctx, w.chainID, globalTx, w.repository, log)
|
||||
} else {
|
||||
log.Warn("transaction has more than one instruction")
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,6 +70,11 @@ func NewTerraWatcher(terraSDK *terra.TerraSDK, params TerraParams, repository *s
|
|||
}
|
||||
}
|
||||
|
||||
// GetBlockchain returns the blockchain name.
|
||||
func (w *TerraWatcher) GetBlockchain() string {
|
||||
return w.blockchain
|
||||
}
|
||||
|
||||
// Start starts the terra watcher.
|
||||
func (w *TerraWatcher) Start(ctx context.Context) error {
|
||||
// get the current block for the chain.
|
||||
|
|
Loading…
Reference in New Issue