github.com/MetalBlockchain/metalgo@v1.11.9/vms/tracedvm/block_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 tracedvm
     5  
     6  import (
     7  	"context"
     8  
     9  	"go.opentelemetry.io/otel/attribute"
    10  
    11  	"github.com/MetalBlockchain/metalgo/database"
    12  	"github.com/MetalBlockchain/metalgo/ids"
    13  	"github.com/MetalBlockchain/metalgo/snow"
    14  	"github.com/MetalBlockchain/metalgo/snow/consensus/snowman"
    15  	"github.com/MetalBlockchain/metalgo/snow/engine/common"
    16  	"github.com/MetalBlockchain/metalgo/snow/engine/snowman/block"
    17  	"github.com/MetalBlockchain/metalgo/trace"
    18  
    19  	oteltrace "go.opentelemetry.io/otel/trace"
    20  )
    21  
    22  var (
    23  	_ block.ChainVM                      = (*blockVM)(nil)
    24  	_ block.BuildBlockWithContextChainVM = (*blockVM)(nil)
    25  	_ block.BatchedChainVM               = (*blockVM)(nil)
    26  	_ block.StateSyncableVM              = (*blockVM)(nil)
    27  )
    28  
    29  type blockVM struct {
    30  	block.ChainVM
    31  	buildBlockVM block.BuildBlockWithContextChainVM
    32  	batchedVM    block.BatchedChainVM
    33  	ssVM         block.StateSyncableVM
    34  	// ChainVM tags
    35  	initializeTag              string
    36  	buildBlockTag              string
    37  	parseBlockTag              string
    38  	getBlockTag                string
    39  	setPreferenceTag           string
    40  	lastAcceptedTag            string
    41  	verifyTag                  string
    42  	acceptTag                  string
    43  	rejectTag                  string
    44  	optionsTag                 string
    45  	shouldVerifyWithContextTag string
    46  	verifyWithContextTag       string
    47  	// BuildBlockWithContextChainVM tags
    48  	buildBlockWithContextTag string
    49  	// BatchedChainVM tags
    50  	getAncestorsTag      string
    51  	batchedParseBlockTag string
    52  	// HeightIndexedChainVM tags
    53  	getBlockIDAtHeightTag string
    54  	// StateSyncableVM tags
    55  	stateSyncEnabledTag           string
    56  	getOngoingSyncStateSummaryTag string
    57  	getLastStateSummaryTag        string
    58  	parseStateSummaryTag          string
    59  	getStateSummaryTag            string
    60  	tracer                        trace.Tracer
    61  }
    62  
    63  func NewBlockVM(vm block.ChainVM, name string, tracer trace.Tracer) block.ChainVM {
    64  	buildBlockVM, _ := vm.(block.BuildBlockWithContextChainVM)
    65  	batchedVM, _ := vm.(block.BatchedChainVM)
    66  	ssVM, _ := vm.(block.StateSyncableVM)
    67  	return &blockVM{
    68  		ChainVM:                       vm,
    69  		buildBlockVM:                  buildBlockVM,
    70  		batchedVM:                     batchedVM,
    71  		ssVM:                          ssVM,
    72  		initializeTag:                 name + ".initialize",
    73  		buildBlockTag:                 name + ".buildBlock",
    74  		parseBlockTag:                 name + ".parseBlock",
    75  		getBlockTag:                   name + ".getBlock",
    76  		setPreferenceTag:              name + ".setPreference",
    77  		lastAcceptedTag:               name + ".lastAccepted",
    78  		verifyTag:                     name + ".verify",
    79  		acceptTag:                     name + ".accept",
    80  		rejectTag:                     name + ".reject",
    81  		optionsTag:                    name + ".options",
    82  		shouldVerifyWithContextTag:    name + ".shouldVerifyWithContext",
    83  		verifyWithContextTag:          name + ".verifyWithContext",
    84  		buildBlockWithContextTag:      name + ".buildBlockWithContext",
    85  		getAncestorsTag:               name + ".getAncestors",
    86  		batchedParseBlockTag:          name + ".batchedParseBlock",
    87  		getBlockIDAtHeightTag:         name + ".getBlockIDAtHeight",
    88  		stateSyncEnabledTag:           name + ".stateSyncEnabled",
    89  		getOngoingSyncStateSummaryTag: name + ".getOngoingSyncStateSummary",
    90  		getLastStateSummaryTag:        name + ".getLastStateSummary",
    91  		parseStateSummaryTag:          name + ".parseStateSummary",
    92  		getStateSummaryTag:            name + ".getStateSummary",
    93  		tracer:                        tracer,
    94  	}
    95  }
    96  
    97  func (vm *blockVM) Initialize(
    98  	ctx context.Context,
    99  	chainCtx *snow.Context,
   100  	db database.Database,
   101  	genesisBytes,
   102  	upgradeBytes,
   103  	configBytes []byte,
   104  	toEngine chan<- common.Message,
   105  	fxs []*common.Fx,
   106  	appSender common.AppSender,
   107  ) error {
   108  	ctx, span := vm.tracer.Start(ctx, vm.initializeTag)
   109  	defer span.End()
   110  
   111  	return vm.ChainVM.Initialize(
   112  		ctx,
   113  		chainCtx,
   114  		db,
   115  		genesisBytes,
   116  		upgradeBytes,
   117  		configBytes,
   118  		toEngine,
   119  		fxs,
   120  		appSender,
   121  	)
   122  }
   123  
   124  func (vm *blockVM) BuildBlock(ctx context.Context) (snowman.Block, error) {
   125  	ctx, span := vm.tracer.Start(ctx, vm.buildBlockTag)
   126  	defer span.End()
   127  
   128  	blk, err := vm.ChainVM.BuildBlock(ctx)
   129  	return &tracedBlock{
   130  		Block: blk,
   131  		vm:    vm,
   132  	}, err
   133  }
   134  
   135  func (vm *blockVM) ParseBlock(ctx context.Context, block []byte) (snowman.Block, error) {
   136  	ctx, span := vm.tracer.Start(ctx, vm.parseBlockTag, oteltrace.WithAttributes(
   137  		attribute.Int("blockLen", len(block)),
   138  	))
   139  	defer span.End()
   140  
   141  	blk, err := vm.ChainVM.ParseBlock(ctx, block)
   142  	return &tracedBlock{
   143  		Block: blk,
   144  		vm:    vm,
   145  	}, err
   146  }
   147  
   148  func (vm *blockVM) GetBlock(ctx context.Context, blkID ids.ID) (snowman.Block, error) {
   149  	ctx, span := vm.tracer.Start(ctx, vm.getBlockTag, oteltrace.WithAttributes(
   150  		attribute.Stringer("blkID", blkID),
   151  	))
   152  	defer span.End()
   153  
   154  	blk, err := vm.ChainVM.GetBlock(ctx, blkID)
   155  	return &tracedBlock{
   156  		Block: blk,
   157  		vm:    vm,
   158  	}, err
   159  }
   160  
   161  func (vm *blockVM) SetPreference(ctx context.Context, blkID ids.ID) error {
   162  	ctx, span := vm.tracer.Start(ctx, vm.setPreferenceTag, oteltrace.WithAttributes(
   163  		attribute.Stringer("blkID", blkID),
   164  	))
   165  	defer span.End()
   166  
   167  	return vm.ChainVM.SetPreference(ctx, blkID)
   168  }
   169  
   170  func (vm *blockVM) LastAccepted(ctx context.Context) (ids.ID, error) {
   171  	ctx, span := vm.tracer.Start(ctx, vm.lastAcceptedTag)
   172  	defer span.End()
   173  
   174  	return vm.ChainVM.LastAccepted(ctx)
   175  }
   176  
   177  func (vm *blockVM) GetBlockIDAtHeight(ctx context.Context, height uint64) (ids.ID, error) {
   178  	ctx, span := vm.tracer.Start(ctx, vm.getBlockIDAtHeightTag, oteltrace.WithAttributes(
   179  		attribute.Int64("height", int64(height)),
   180  	))
   181  	defer span.End()
   182  
   183  	return vm.ChainVM.GetBlockIDAtHeight(ctx, height)
   184  }