code.vegaprotocol.io/vega@v0.79.0/core/blockchain/abci/app.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package abci 17 18 import ( 19 "context" 20 21 "code.vegaprotocol.io/vega/core/blockchain" 22 "code.vegaprotocol.io/vega/core/txn" 23 "code.vegaprotocol.io/vega/core/types" 24 25 abci "github.com/cometbft/cometbft/abci/types" 26 lru "github.com/hashicorp/golang-lru" 27 ) 28 29 type ( 30 Command byte 31 TxHandler func(ctx context.Context, tx Tx) error 32 ) 33 34 type SnapshotEngine interface { 35 AddProviders(provs ...types.StateProvider) 36 } 37 38 type App struct { 39 abci.BaseApplication 40 codec Codec 41 42 // handlers 43 OnPrepareProposal PrepareProposalHandler 44 OnProcessProposal ProcessProposalHandler 45 OnInitChain OnInitChainHandler 46 OnCheckTx OnCheckTxHandler 47 OnCommit OnCommitHandler 48 OnBeginBlock OnBeginBlockHandler 49 OnEndBlock OnEndBlockHandler 50 OnFinalize FinalizeHandler 51 52 // spam check 53 OnCheckTxSpam OnCheckTxSpamHandler 54 55 // snapshot stuff 56 57 OnListSnapshots ListSnapshotsHandler 58 OnOfferSnapshot OfferSnapshotHandler 59 OnLoadSnapshotChunk LoadSnapshotChunkHandler 60 OnApplySnapshotChunk ApplySnapshotChunkHandler 61 OnInfo InfoHandler 62 63 // These are Tx handlers 64 checkTxs map[txn.Command]TxHandler 65 deliverTxs map[txn.Command]TxHandler 66 67 // checkedTxs holds a map of valid transactions (validated by CheckTx) 68 // They are consumed by DeliverTx to avoid double validation. 69 checkedTxs *lru.Cache // map[string]Transaction 70 71 // the current block context 72 ctx context.Context 73 74 chainID string 75 } 76 77 func New(codec Codec) *App { 78 lruCache, _ := lru.New(1024) 79 return &App{ 80 codec: codec, 81 checkTxs: map[txn.Command]TxHandler{}, 82 deliverTxs: map[txn.Command]TxHandler{}, 83 checkedTxs: lruCache, 84 ctx: context.Background(), 85 } 86 } 87 88 func (app *App) SetChainID(chainID string) { 89 app.chainID = chainID 90 } 91 92 func (app *App) GetChainID() string { 93 return app.chainID 94 } 95 96 func (app *App) HandleCheckTx(cmd txn.Command, fn TxHandler) *App { 97 app.checkTxs[cmd] = fn 98 return app 99 } 100 101 func (app *App) HandleDeliverTx(cmd txn.Command, fn TxHandler) *App { 102 app.deliverTxs[cmd] = fn 103 return app 104 } 105 106 func (app *App) decodeTx(bytes []byte) (Tx, uint32, error) { 107 tx, err := app.codec.Decode(bytes, app.chainID) 108 if err != nil { 109 return nil, blockchain.AbciTxnDecodingFailure, err 110 } 111 return tx, 0, nil 112 } 113 114 // cacheTx adds a Tx to the cache. 115 func (app *App) cacheTx(in []byte, tx Tx) { 116 app.checkedTxs.Add(string(in), tx) 117 } 118 119 // txFromCache retrieves (and remove if found) a Tx from the cache, 120 // it returns the Tx or nil if not found. 121 func (app *App) txFromCache(in []byte) Tx { 122 tx, ok := app.checkedTxs.Get(string(in)) 123 if !ok { 124 return nil 125 } 126 127 return tx.(Tx) 128 } 129 130 func (app *App) removeTxFromCache(in []byte) { 131 app.checkedTxs.Remove(string(in)) 132 } 133 134 // getTx returns an internal Tx given a []byte. 135 // An error code different from 0 is returned if decoding fails with its the corresponding error. 136 func (app *App) getTx(bytes []byte) (Tx, uint32, error) { 137 if tx := app.txFromCache(bytes); tx != nil { 138 return tx, 0, nil 139 } 140 141 tx, code, err := app.decodeTx(bytes) 142 if err != nil { 143 return nil, code, err 144 } 145 146 return tx, 0, nil 147 }