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 }