code.vegaprotocol.io/vega@v0.79.0/commands/transaction_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 commands_test 17 18 import ( 19 "errors" 20 "testing" 21 22 "code.vegaprotocol.io/vega/commands" 23 "code.vegaprotocol.io/vega/libs/crypto" 24 commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1" 25 26 "github.com/stretchr/testify/assert" 27 "github.com/stretchr/testify/require" 28 "google.golang.org/protobuf/proto" 29 ) 30 31 func TestCheckTransaction(t *testing.T) { 32 t.Run("Submitting valid transaction succeeds", testSubmittingInvalidSignature) 33 t.Run("Submitting valid transaction succeeds", testSubmittingValidTransactionSucceeds) 34 t.Run("Submitting empty transaction fails", testSubmittingEmptyTransactionFails) 35 t.Run("Submitting nil transaction fails", testSubmittingNilTransactionFails) 36 t.Run("Submitting transaction without version fails", testSubmittingTransactionWithoutVersionFails) 37 t.Run("Submitting transaction with unsupported version fails", testSubmittingTransactionWithUnsupportedVersionFails) 38 t.Run("Submitting transaction without input data fails", testSubmittingTransactionWithoutInputDataFails) 39 t.Run("Submitting transaction without signature fails", testSubmittingTransactionWithoutSignatureFails) 40 t.Run("Submitting transaction without signature value fails", testSubmittingTransactionWithoutSignatureValueFails) 41 t.Run("Submitting transaction without signature algo fails", testSubmittingTransactionWithoutSignatureAlgoFails) 42 t.Run("Submitting transaction without from fails", testSubmittingTransactionWithoutFromFails) 43 t.Run("Submitting transaction without public key fails", testSubmittingTransactionWithoutPubKeyFromFails) 44 t.Run("Submitting transaction with invalid encoding of value fails", testSubmittingTransactionWithInvalidEncodingOfValueFails) 45 t.Run("Submitting transaction with invalid encoding of public key fails", testSubmittingTransactionWithInvalidEncodingOfPubKeyFails) 46 } 47 48 func testSubmittingInvalidSignature(t *testing.T) { 49 tx := newValidTransactionV2(t) 50 tx.Signature = &commandspb.Signature{ 51 Value: crypto.RandomHash(), 52 Algo: "vega/ed25519", 53 Version: 1, 54 } 55 err := checkTransaction(tx) 56 require.Error(t, err) 57 require.Equal(t, commands.ErrInvalidSignature, err["tx.signature.value"][0]) 58 } 59 60 func testSubmittingValidTransactionSucceeds(t *testing.T) { 61 tx := newValidTransactionV2(t) 62 63 err := checkTransaction(tx) 64 65 assert.True(t, err.Empty(), err.Error()) 66 } 67 68 func testSubmittingEmptyTransactionFails(t *testing.T) { 69 err := checkTransaction(&commandspb.Transaction{}) 70 71 assert.Error(t, err) 72 } 73 74 func testSubmittingNilTransactionFails(t *testing.T) { 75 err := checkTransaction(nil) 76 77 assert.Contains(t, err.Get("tx"), commands.ErrIsRequired) 78 } 79 80 func testSubmittingTransactionWithoutVersionFails(t *testing.T) { 81 tx := newValidTransactionV2(t) 82 tx.Version = 0 83 84 err := checkTransaction(tx) 85 86 assert.Contains(t, err.Get("tx.version"), commands.ErrIsRequired) 87 } 88 89 func testSubmittingTransactionWithUnsupportedVersionFails(t *testing.T) { 90 tcs := []struct { 91 name string 92 version uint32 93 }{ 94 { 95 name: "version 1", 96 version: 1, 97 }, { 98 name: "version 4", 99 version: 4, 100 }, 101 } 102 103 for _, tc := range tcs { 104 t.Run(tc.name, func(tt *testing.T) { 105 tx := newValidTransactionV2(tt) 106 tx.Version = commandspb.TxVersion(tc.version) 107 108 err := checkTransaction(tx) 109 110 assert.Contains(tt, err.Get("tx.version"), commands.ErrIsNotSupported) 111 }) 112 } 113 } 114 115 func testSubmittingTransactionWithoutInputDataFails(t *testing.T) { 116 tx := newValidTransactionV2(t) 117 tx.InputData = []byte{} 118 119 err := checkTransaction(tx) 120 121 assert.Contains(t, err.Get("tx.input_data"), commands.ErrIsRequired) 122 } 123 124 func testSubmittingTransactionWithoutSignatureFails(t *testing.T) { 125 tx := newValidTransactionV2(t) 126 tx.Signature = nil 127 128 err := checkTransaction(tx) 129 130 assert.Contains(t, err.Get("tx.signature"), commands.ErrIsRequired) 131 } 132 133 func testSubmittingTransactionWithoutSignatureValueFails(t *testing.T) { 134 tx := newValidTransactionV2(t) 135 tx.Signature.Value = "" 136 137 err := checkTransaction(tx) 138 139 assert.Contains(t, err.Get("tx.signature.value"), commands.ErrIsRequired) 140 } 141 142 func testSubmittingTransactionWithoutSignatureAlgoFails(t *testing.T) { 143 tx := newValidTransactionV2(t) 144 tx.Signature.Algo = "" 145 146 err := checkTransaction(tx) 147 148 assert.Contains(t, err.Get("tx.signature.algo"), commands.ErrIsRequired) 149 } 150 151 func testSubmittingTransactionWithoutFromFails(t *testing.T) { 152 tx := newValidTransactionV2(t) 153 tx.From = nil 154 155 err := checkTransaction(tx) 156 157 assert.Contains(t, err.Get("tx.from"), commands.ErrIsRequired) 158 } 159 160 func testSubmittingTransactionWithoutPubKeyFromFails(t *testing.T) { 161 tx := newValidTransactionV2(t) 162 tx.From = &commandspb.Transaction_PubKey{ 163 PubKey: "", 164 } 165 166 err := checkTransaction(tx) 167 168 assert.Contains(t, err.Get("tx.from.pub_key"), commands.ErrIsRequired) 169 } 170 171 func testSubmittingTransactionWithInvalidEncodingOfValueFails(t *testing.T) { 172 tx := newValidTransactionV2(t) 173 tx.Signature.Value = "invalid-hex-encoding" 174 175 err := checkTransaction(tx) 176 177 assert.Contains(t, err.Get("tx.signature.value"), commands.ErrShouldBeHexEncoded, err.Error()) 178 } 179 180 func testSubmittingTransactionWithInvalidEncodingOfPubKeyFails(t *testing.T) { 181 tx := newValidTransactionV2(t) 182 tx.From = &commandspb.Transaction_PubKey{ 183 PubKey: "my-pub-key", 184 } 185 186 err := checkTransaction(tx) 187 188 assert.Contains(t, err.Get("tx.from.pub_key"), commands.ErrShouldBeAValidVegaPublicKey) 189 } 190 191 func checkTransaction(cmd *commandspb.Transaction) commands.Errors { 192 _, err := commands.CheckTransaction(cmd, "testnet") 193 194 var e commands.Errors 195 if ok := errors.As(err, &e); !ok { 196 return commands.NewErrors() 197 } 198 199 return e 200 } 201 202 func newValidTransactionV2(t *testing.T) *commandspb.Transaction { 203 t.Helper() 204 205 inputData := &commandspb.InputData{ 206 Nonce: 123456789, 207 BlockHeight: 1789, 208 Command: &commandspb.InputData_OrderCancellation{ 209 OrderCancellation: &commandspb.OrderCancellation{ 210 MarketId: "USD/BTC", 211 OrderId: "7fa6d9f6a9dfa9f66fada", 212 }, 213 }, 214 } 215 216 rawInputData, err := proto.Marshal(inputData) 217 if err != nil { 218 t.Fatal(err) 219 } 220 221 return &commandspb.Transaction{ 222 InputData: rawInputData, 223 Signature: &commandspb.Signature{ 224 Algo: "vega/ed25519", 225 Value: "876e46defc40030391b5feb2c9bb0b6b68b2d95a6b5fd17a730a46ea73f3b1808420c8c609be6f1c6156e472ecbcd09202f750da000dee41429947a4b7eca00b", 226 Version: 1, 227 }, 228 From: &commandspb.Transaction_PubKey{ 229 PubKey: "b5fd9d3c4ad553cb3196303b6e6df7f484cf7f5331a572a45031239fd71ad8a0", 230 }, 231 Version: 2, 232 } 233 }