github.com/ava-labs/avalanchego@v1.11.11/vms/metervm/block.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  	"errors"
     9  	"fmt"
    10  
    11  	"github.com/ava-labs/avalanchego/snow/consensus/snowman"
    12  	"github.com/ava-labs/avalanchego/snow/engine/snowman/block"
    13  )
    14  
    15  var (
    16  	_ snowman.Block           = (*meterBlock)(nil)
    17  	_ snowman.OracleBlock     = (*meterBlock)(nil)
    18  	_ block.WithVerifyContext = (*meterBlock)(nil)
    19  
    20  	errExpectedBlockWithVerifyContext = errors.New("expected block.WithVerifyContext")
    21  )
    22  
    23  type meterBlock struct {
    24  	snowman.Block
    25  
    26  	vm *blockVM
    27  }
    28  
    29  func (mb *meterBlock) Verify(ctx context.Context) error {
    30  	start := mb.vm.clock.Time()
    31  	err := mb.Block.Verify(ctx)
    32  	end := mb.vm.clock.Time()
    33  	duration := float64(end.Sub(start))
    34  	if err != nil {
    35  		mb.vm.blockMetrics.verifyErr.Observe(duration)
    36  	} else {
    37  		mb.vm.verify.Observe(duration)
    38  	}
    39  	return err
    40  }
    41  
    42  func (mb *meterBlock) Accept(ctx context.Context) error {
    43  	start := mb.vm.clock.Time()
    44  	err := mb.Block.Accept(ctx)
    45  	end := mb.vm.clock.Time()
    46  	duration := float64(end.Sub(start))
    47  	mb.vm.blockMetrics.accept.Observe(duration)
    48  	return err
    49  }
    50  
    51  func (mb *meterBlock) Reject(ctx context.Context) error {
    52  	start := mb.vm.clock.Time()
    53  	err := mb.Block.Reject(ctx)
    54  	end := mb.vm.clock.Time()
    55  	duration := float64(end.Sub(start))
    56  	mb.vm.blockMetrics.reject.Observe(duration)
    57  	return err
    58  }
    59  
    60  func (mb *meterBlock) Options(ctx context.Context) ([2]snowman.Block, error) {
    61  	oracleBlock, ok := mb.Block.(snowman.OracleBlock)
    62  	if !ok {
    63  		return [2]snowman.Block{}, snowman.ErrNotOracle
    64  	}
    65  
    66  	blks, err := oracleBlock.Options(ctx)
    67  	if err != nil {
    68  		return [2]snowman.Block{}, err
    69  	}
    70  	return [2]snowman.Block{
    71  		&meterBlock{
    72  			Block: blks[0],
    73  			vm:    mb.vm,
    74  		},
    75  		&meterBlock{
    76  			Block: blks[1],
    77  			vm:    mb.vm,
    78  		},
    79  	}, nil
    80  }
    81  
    82  func (mb *meterBlock) ShouldVerifyWithContext(ctx context.Context) (bool, error) {
    83  	blkWithCtx, ok := mb.Block.(block.WithVerifyContext)
    84  	if !ok {
    85  		return false, nil
    86  	}
    87  
    88  	start := mb.vm.clock.Time()
    89  	shouldVerify, err := blkWithCtx.ShouldVerifyWithContext(ctx)
    90  	end := mb.vm.clock.Time()
    91  	duration := float64(end.Sub(start))
    92  	mb.vm.blockMetrics.shouldVerifyWithContext.Observe(duration)
    93  	return shouldVerify, err
    94  }
    95  
    96  func (mb *meterBlock) VerifyWithContext(ctx context.Context, blockCtx *block.Context) error {
    97  	blkWithCtx, ok := mb.Block.(block.WithVerifyContext)
    98  	if !ok {
    99  		return fmt.Errorf("%w but got %T", errExpectedBlockWithVerifyContext, mb.Block)
   100  	}
   101  
   102  	start := mb.vm.clock.Time()
   103  	err := blkWithCtx.VerifyWithContext(ctx, blockCtx)
   104  	end := mb.vm.clock.Time()
   105  	duration := float64(end.Sub(start))
   106  	if err != nil {
   107  		mb.vm.blockMetrics.verifyWithContextErr.Observe(duration)
   108  	} else {
   109  		mb.vm.verifyWithContext.Observe(duration)
   110  	}
   111  	return err
   112  }