github.com/ava-labs/avalanchego@v1.11.11/vms/platformvm/block/executor/manager.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package executor
     5  
     6  import (
     7  	"errors"
     8  
     9  	"github.com/ava-labs/avalanchego/ids"
    10  	"github.com/ava-labs/avalanchego/snow/consensus/snowman"
    11  	"github.com/ava-labs/avalanchego/utils/set"
    12  	"github.com/ava-labs/avalanchego/vms/platformvm/block"
    13  	"github.com/ava-labs/avalanchego/vms/platformvm/metrics"
    14  	"github.com/ava-labs/avalanchego/vms/platformvm/state"
    15  	"github.com/ava-labs/avalanchego/vms/platformvm/txs"
    16  	"github.com/ava-labs/avalanchego/vms/platformvm/txs/executor"
    17  	"github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool"
    18  	"github.com/ava-labs/avalanchego/vms/platformvm/validators"
    19  )
    20  
    21  var (
    22  	_ Manager = (*manager)(nil)
    23  
    24  	ErrChainNotSynced = errors.New("chain not synced")
    25  )
    26  
    27  type Manager interface {
    28  	state.Versions
    29  
    30  	// Returns the ID of the most recently accepted block.
    31  	LastAccepted() ids.ID
    32  
    33  	SetPreference(blkID ids.ID) (updated bool)
    34  	Preferred() ids.ID
    35  
    36  	GetBlock(blkID ids.ID) (snowman.Block, error)
    37  	GetStatelessBlock(blkID ids.ID) (block.Block, error)
    38  	NewBlock(block.Block) snowman.Block
    39  
    40  	// VerifyTx verifies that the transaction can be issued based on the currently
    41  	// preferred state. This should *not* be used to verify transactions in a block.
    42  	VerifyTx(tx *txs.Tx) error
    43  
    44  	// VerifyUniqueInputs verifies that the inputs are not duplicated in the
    45  	// provided blk or any of its ancestors pinned in memory.
    46  	VerifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error
    47  }
    48  
    49  func NewManager(
    50  	mempool mempool.Mempool,
    51  	metrics metrics.Metrics,
    52  	s state.State,
    53  	txExecutorBackend *executor.Backend,
    54  	validatorManager validators.Manager,
    55  ) Manager {
    56  	lastAccepted := s.GetLastAccepted()
    57  	backend := &backend{
    58  		Mempool:      mempool,
    59  		lastAccepted: lastAccepted,
    60  		state:        s,
    61  		ctx:          txExecutorBackend.Ctx,
    62  		blkIDToState: map[ids.ID]*blockState{},
    63  	}
    64  
    65  	return &manager{
    66  		backend: backend,
    67  		acceptor: &acceptor{
    68  			backend:      backend,
    69  			metrics:      metrics,
    70  			validators:   validatorManager,
    71  			bootstrapped: txExecutorBackend.Bootstrapped,
    72  		},
    73  		rejector: &rejector{
    74  			backend:         backend,
    75  			addTxsToMempool: !txExecutorBackend.Config.PartialSyncPrimaryNetwork,
    76  		},
    77  		preferred:         lastAccepted,
    78  		txExecutorBackend: txExecutorBackend,
    79  	}
    80  }
    81  
    82  type manager struct {
    83  	*backend
    84  	acceptor block.Visitor
    85  	rejector block.Visitor
    86  
    87  	preferred         ids.ID
    88  	txExecutorBackend *executor.Backend
    89  }
    90  
    91  func (m *manager) GetBlock(blkID ids.ID) (snowman.Block, error) {
    92  	blk, err := m.backend.GetBlock(blkID)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	return m.NewBlock(blk), nil
    97  }
    98  
    99  func (m *manager) GetStatelessBlock(blkID ids.ID) (block.Block, error) {
   100  	return m.backend.GetBlock(blkID)
   101  }
   102  
   103  func (m *manager) NewBlock(blk block.Block) snowman.Block {
   104  	return &Block{
   105  		manager: m,
   106  		Block:   blk,
   107  	}
   108  }
   109  
   110  func (m *manager) SetPreference(blkID ids.ID) bool {
   111  	updated := m.preferred != blkID
   112  	m.preferred = blkID
   113  	return updated
   114  }
   115  
   116  func (m *manager) Preferred() ids.ID {
   117  	return m.preferred
   118  }
   119  
   120  func (m *manager) VerifyTx(tx *txs.Tx) error {
   121  	if !m.txExecutorBackend.Bootstrapped.Get() {
   122  		return ErrChainNotSynced
   123  	}
   124  
   125  	stateDiff, err := state.NewDiff(m.preferred, m)
   126  	if err != nil {
   127  		return err
   128  	}
   129  
   130  	nextBlkTime, _, err := state.NextBlockTime(stateDiff, m.txExecutorBackend.Clk)
   131  	if err != nil {
   132  		return err
   133  	}
   134  
   135  	_, err = executor.AdvanceTimeTo(m.txExecutorBackend, stateDiff, nextBlkTime)
   136  	if err != nil {
   137  		return err
   138  	}
   139  
   140  	feeCalculator := state.PickFeeCalculator(m.txExecutorBackend.Config, stateDiff)
   141  	return tx.Unsigned.Visit(&executor.StandardTxExecutor{
   142  		Backend:       m.txExecutorBackend,
   143  		State:         stateDiff,
   144  		FeeCalculator: feeCalculator,
   145  		Tx:            tx,
   146  	})
   147  }
   148  
   149  func (m *manager) VerifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error {
   150  	return m.backend.verifyUniqueInputs(blkID, inputs)
   151  }