github.com/MetalBlockchain/metalgo@v1.11.9/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/MetalBlockchain/metalgo/ids" 10 "github.com/MetalBlockchain/metalgo/snow/consensus/snowman" 11 "github.com/MetalBlockchain/metalgo/utils/set" 12 "github.com/MetalBlockchain/metalgo/vms/platformvm/block" 13 "github.com/MetalBlockchain/metalgo/vms/platformvm/metrics" 14 "github.com/MetalBlockchain/metalgo/vms/platformvm/state" 15 "github.com/MetalBlockchain/metalgo/vms/platformvm/txs" 16 "github.com/MetalBlockchain/metalgo/vms/platformvm/txs/executor" 17 "github.com/MetalBlockchain/metalgo/vms/platformvm/txs/mempool" 18 "github.com/MetalBlockchain/metalgo/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 verifier: &verifier{ 68 backend: backend, 69 txExecutorBackend: txExecutorBackend, 70 }, 71 acceptor: &acceptor{ 72 backend: backend, 73 metrics: metrics, 74 validators: validatorManager, 75 bootstrapped: txExecutorBackend.Bootstrapped, 76 }, 77 rejector: &rejector{ 78 backend: backend, 79 addTxsToMempool: !txExecutorBackend.Config.PartialSyncPrimaryNetwork, 80 }, 81 preferred: lastAccepted, 82 txExecutorBackend: txExecutorBackend, 83 } 84 } 85 86 type manager struct { 87 *backend 88 verifier block.Visitor 89 acceptor block.Visitor 90 rejector block.Visitor 91 92 preferred ids.ID 93 txExecutorBackend *executor.Backend 94 } 95 96 func (m *manager) GetBlock(blkID ids.ID) (snowman.Block, error) { 97 blk, err := m.backend.GetBlock(blkID) 98 if err != nil { 99 return nil, err 100 } 101 return m.NewBlock(blk), nil 102 } 103 104 func (m *manager) GetStatelessBlock(blkID ids.ID) (block.Block, error) { 105 return m.backend.GetBlock(blkID) 106 } 107 108 func (m *manager) NewBlock(blk block.Block) snowman.Block { 109 return &Block{ 110 manager: m, 111 Block: blk, 112 } 113 } 114 115 func (m *manager) SetPreference(blkID ids.ID) bool { 116 updated := m.preferred != blkID 117 m.preferred = blkID 118 return updated 119 } 120 121 func (m *manager) Preferred() ids.ID { 122 return m.preferred 123 } 124 125 func (m *manager) VerifyTx(tx *txs.Tx) error { 126 if !m.txExecutorBackend.Bootstrapped.Get() { 127 return ErrChainNotSynced 128 } 129 130 stateDiff, err := state.NewDiff(m.preferred, m) 131 if err != nil { 132 return err 133 } 134 135 nextBlkTime, _, err := state.NextBlockTime(stateDiff, m.txExecutorBackend.Clk) 136 if err != nil { 137 return err 138 } 139 140 _, err = executor.AdvanceTimeTo(m.txExecutorBackend, stateDiff, nextBlkTime) 141 if err != nil { 142 return err 143 } 144 145 return tx.Unsigned.Visit(&executor.StandardTxExecutor{ 146 Backend: m.txExecutorBackend, 147 State: stateDiff, 148 Tx: tx, 149 }) 150 } 151 152 func (m *manager) VerifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error { 153 return m.backend.verifyUniqueInputs(blkID, inputs) 154 }