github.com/MetalBlockchain/metalgo@v1.11.9/vms/metervm/vertex_vm.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package metervm
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/prometheus/client_golang/prometheus"
    10  
    11  	"github.com/MetalBlockchain/metalgo/database"
    12  	"github.com/MetalBlockchain/metalgo/snow"
    13  	"github.com/MetalBlockchain/metalgo/snow/consensus/snowstorm"
    14  	"github.com/MetalBlockchain/metalgo/snow/engine/avalanche/vertex"
    15  	"github.com/MetalBlockchain/metalgo/snow/engine/common"
    16  	"github.com/MetalBlockchain/metalgo/utils/timer/mockable"
    17  )
    18  
    19  var (
    20  	_ vertex.LinearizableVMWithEngine = (*vertexVM)(nil)
    21  	_ snowstorm.Tx                    = (*meterTx)(nil)
    22  )
    23  
    24  func NewVertexVM(
    25  	vm vertex.LinearizableVMWithEngine,
    26  	reg prometheus.Registerer,
    27  ) vertex.LinearizableVMWithEngine {
    28  	return &vertexVM{
    29  		LinearizableVMWithEngine: vm,
    30  		registry:                 reg,
    31  	}
    32  }
    33  
    34  type vertexVM struct {
    35  	vertex.LinearizableVMWithEngine
    36  	vertexMetrics
    37  	registry prometheus.Registerer
    38  	clock    mockable.Clock
    39  }
    40  
    41  func (vm *vertexVM) Initialize(
    42  	ctx context.Context,
    43  	chainCtx *snow.Context,
    44  	db database.Database,
    45  	genesisBytes,
    46  	upgradeBytes,
    47  	configBytes []byte,
    48  	toEngine chan<- common.Message,
    49  	fxs []*common.Fx,
    50  	appSender common.AppSender,
    51  ) error {
    52  	if err := vm.vertexMetrics.Initialize(vm.registry); err != nil {
    53  		return err
    54  	}
    55  
    56  	return vm.LinearizableVMWithEngine.Initialize(
    57  		ctx,
    58  		chainCtx,
    59  		db,
    60  		genesisBytes,
    61  		upgradeBytes,
    62  		configBytes,
    63  		toEngine,
    64  		fxs,
    65  		appSender,
    66  	)
    67  }
    68  
    69  func (vm *vertexVM) ParseTx(ctx context.Context, b []byte) (snowstorm.Tx, error) {
    70  	start := vm.clock.Time()
    71  	tx, err := vm.LinearizableVMWithEngine.ParseTx(ctx, b)
    72  	end := vm.clock.Time()
    73  	duration := float64(end.Sub(start))
    74  	if err != nil {
    75  		vm.vertexMetrics.parseErr.Observe(duration)
    76  		return nil, err
    77  	}
    78  	vm.vertexMetrics.parse.Observe(duration)
    79  	return &meterTx{
    80  		Tx: tx,
    81  		vm: vm,
    82  	}, nil
    83  }
    84  
    85  type meterTx struct {
    86  	snowstorm.Tx
    87  
    88  	vm *vertexVM
    89  }
    90  
    91  func (mtx *meterTx) Verify(ctx context.Context) error {
    92  	start := mtx.vm.clock.Time()
    93  	err := mtx.Tx.Verify(ctx)
    94  	end := mtx.vm.clock.Time()
    95  	duration := float64(end.Sub(start))
    96  	if err != nil {
    97  		mtx.vm.vertexMetrics.verifyErr.Observe(duration)
    98  	} else {
    99  		mtx.vm.vertexMetrics.verify.Observe(duration)
   100  	}
   101  	return err
   102  }
   103  
   104  func (mtx *meterTx) Accept(ctx context.Context) error {
   105  	start := mtx.vm.clock.Time()
   106  	err := mtx.Tx.Accept(ctx)
   107  	end := mtx.vm.clock.Time()
   108  	mtx.vm.vertexMetrics.accept.Observe(float64(end.Sub(start)))
   109  	return err
   110  }
   111  
   112  func (mtx *meterTx) Reject(ctx context.Context) error {
   113  	start := mtx.vm.clock.Time()
   114  	err := mtx.Tx.Reject(ctx)
   115  	end := mtx.vm.clock.Time()
   116  	mtx.vm.vertexMetrics.reject.Observe(float64(end.Sub(start)))
   117  	return err
   118  }