github.com/MetalBlockchain/metalgo@v1.11.9/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/MetalBlockchain/metalgo/snow/consensus/snowman" 12 "github.com/MetalBlockchain/metalgo/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 }