code.vegaprotocol.io/vega@v0.79.0/core/blockchain/abci/abci_test.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_test 17 18 import ( 19 "context" 20 "encoding/hex" 21 "errors" 22 "testing" 23 24 "code.vegaprotocol.io/vega/core/blockchain" 25 "code.vegaprotocol.io/vega/core/blockchain/abci" 26 "code.vegaprotocol.io/vega/core/txn" 27 28 "github.com/cometbft/cometbft/abci/types" 29 "github.com/stretchr/testify/require" 30 ) 31 32 type testTx struct { 33 payload []byte 34 pubkey []byte 35 hash []byte 36 signature []byte 37 command txn.Command 38 blockHeight uint64 39 powNonce uint64 40 powTxID string 41 } 42 43 func (tx *testTx) GetLength() int { return 0 } 44 func (tx *testTx) Unmarshal(interface{}) error { return nil } 45 func (tx *testTx) GetPoWTID() string { return tx.powTxID } 46 func (tx *testTx) GetVersion() uint32 { return 2 } 47 func (tx *testTx) GetPoWNonce() uint64 { return tx.powNonce } 48 func (tx *testTx) GetNonce() uint64 { return 0 } 49 func (tx *testTx) Signature() []byte { return tx.signature } 50 func (tx *testTx) Payload() []byte { return tx.payload } 51 func (tx *testTx) PubKey() []byte { return tx.pubkey } 52 func (tx *testTx) PubKeyHex() string { return hex.EncodeToString(tx.pubkey) } 53 func (tx *testTx) Party() string { return hex.EncodeToString(tx.pubkey) } 54 func (tx *testTx) Hash() []byte { return tx.hash } 55 func (tx *testTx) Command() txn.Command { return tx.command } 56 func (tx *testTx) BlockHeight() uint64 { return tx.blockHeight } 57 func (tx *testTx) GetCmd() interface{} { return nil } 58 59 type testCodec struct { 60 txs map[string]abci.Tx 61 } 62 63 func newTestCodec() *testCodec { 64 return &testCodec{ 65 txs: map[string]abci.Tx{}, 66 } 67 } 68 69 func (c *testCodec) addTx(in []byte, tx abci.Tx) { 70 c.txs[string(in)] = tx 71 } 72 73 func (c *testCodec) Decode(in []byte, chainID string) (abci.Tx, error) { 74 tx, ok := c.txs[string(in)] 75 if !ok { 76 return nil, errors.New("tx not defined") 77 } 78 return tx, nil 79 } 80 81 const ( 82 testCommandA = txn.Command(0x01) 83 testCommandB = txn.Command(0x02) 84 ) 85 86 type testCtxKey int 87 88 var testKey testCtxKey 89 90 func TestABCICheckTx(t *testing.T) { 91 cdc := newTestCodec() 92 93 app := abci.New(cdc). 94 HandleCheckTx(testCommandA, func(ctx context.Context, tx abci.Tx) error { 95 require.Equal(t, "val", ctx.Value(testKey)) 96 return nil 97 }). 98 HandleCheckTx(testCommandB, func(ctx context.Context, tx abci.Tx) error { 99 require.Equal(t, "val", ctx.Value(testKey)) 100 return errors.New("boom") 101 }) 102 103 app.OnCheckTx = func(ctx context.Context, _ *types.RequestCheckTx, _ abci.Tx) (context.Context, *types.ResponseCheckTx) { 104 return context.WithValue(ctx, testKey, "val"), &types.ResponseCheckTx{} 105 } 106 107 t.Run("CommandWithNoError", func(t *testing.T) { 108 tx := []byte("tx1") 109 cdc.addTx(tx, &testTx{ 110 command: testCommandA, 111 }) 112 113 req := types.RequestCheckTx{Tx: tx} 114 resp, _ := app.CheckTx(context.Background(), &req) 115 require.True(t, resp.IsOK()) 116 }) 117 118 t.Run("CommandWithError", func(t *testing.T) { 119 tx := []byte("tx2") 120 cdc.addTx(tx, &testTx{ 121 command: testCommandB, 122 }) 123 124 req := types.RequestCheckTx{Tx: tx} 125 resp, _ := app.CheckTx(context.Background(), &req) 126 require.True(t, resp.IsErr()) 127 require.Equal(t, blockchain.AbciTxnInternalError, resp.Code) 128 }) 129 130 t.Run("TxDecodingError", func(t *testing.T) { 131 tx := []byte("tx-not-registered-on-the-codec") 132 133 req := types.RequestCheckTx{Tx: tx} 134 resp, _ := app.CheckTx(context.Background(), &req) 135 require.True(t, resp.IsErr()) 136 require.Equal(t, blockchain.AbciTxnDecodingFailure, resp.Code) 137 }) 138 }