code.vegaprotocol.io/vega@v0.79.0/vegatools/checktx/check.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 checktx
    17  
    18  import (
    19  	"encoding/base64"
    20  	"fmt"
    21  
    22  	"code.vegaprotocol.io/vega/libs/proto"
    23  	commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
    24  
    25  	"github.com/google/go-cmp/cmp"
    26  	"github.com/sirupsen/logrus"
    27  )
    28  
    29  func CheckTransaction(encodedTransaction string) error {
    30  	logrus.Infof("checking transaction...")
    31  	unmarshalledTransaction, err := decodeAndUnmarshalTransaction(encodedTransaction)
    32  	if err != nil {
    33  		return fmt.Errorf("error occurred when attempting to unmarshal the encoded transaction data.\nerr: %w", err)
    34  	}
    35  
    36  	logrus.Infof("reencoding the transaction...")
    37  	reEncodedTransaction, err := marshalAndEncodeTransaction(unmarshalledTransaction)
    38  	if err != nil {
    39  		return fmt.Errorf("error occurred when attempting to marshal and re-encode the transaction")
    40  	}
    41  
    42  	if !cmp.Equal(encodedTransaction, reEncodedTransaction) {
    43  		logrus.Errorf("transactions not equal!")
    44  		return fmt.Errorf("the reencoded transaction was not equal. \nOriginal: %s\nVegaEncoded: %s", encodedTransaction, reEncodedTransaction)
    45  	}
    46  
    47  	logrus.Infof("transactions equal!")
    48  	return nil
    49  }
    50  
    51  type ResultData struct {
    52  	TransactionsPassed   int
    53  	TransactionsFailed   int
    54  	TransactionsAnalysed int
    55  }
    56  
    57  func CheckTransactionsInDirectory(transactionDir string) (ResultData, error) {
    58  	resultData := ResultData{}
    59  	files, err := GetFilesInDirectory(transactionDir)
    60  	if err != nil {
    61  		return resultData, fmt.Errorf("error occurred when attempting to retrieve files from directory %s\nerr: %w", transactionDir, err)
    62  	}
    63  
    64  	for _, file := range files {
    65  		transaction, err := GetEncodedTransactionFromFile(file)
    66  		if err != nil {
    67  			return resultData, fmt.Errorf("error getting encoded data from file '%s', the transaction could not be analysed, check your data is base64 encoded\nerr: %w", file, err)
    68  		}
    69  
    70  		logrus.Infof("inspecting encoded data in file %s", file)
    71  		err = CheckTransaction(transaction)
    72  		if err != nil {
    73  			resultData.TransactionsFailed += 1
    74  			logrus.Errorf("Transaction Failed! | Test file: %s | Error: %v", file, err)
    75  		} else {
    76  			resultData.TransactionsPassed += 1
    77  		}
    78  		resultData.TransactionsAnalysed += 1
    79  	}
    80  
    81  	return resultData, nil
    82  }
    83  
    84  func decodeAndUnmarshalTransaction(encodedTransaction string) (*commandspb.Transaction, error) {
    85  	unmarshalledTransaction := &commandspb.Transaction{}
    86  	decodedBytes, err := base64.StdEncoding.DecodeString(encodedTransaction)
    87  	if err != nil {
    88  		return unmarshalledTransaction, fmt.Errorf("error occurred when decoding the encoded data.\nerr: %w", err)
    89  	}
    90  
    91  	if err := proto.Unmarshal(decodedBytes, unmarshalledTransaction); err != nil {
    92  		return unmarshalledTransaction, fmt.Errorf("unable to unmarshal the decoded bytes to a transaction: %w", err)
    93  	}
    94  
    95  	logrus.Infof("successfully decoded and unmarshalled the transaction")
    96  
    97  	return unmarshalledTransaction, nil
    98  }
    99  
   100  func marshalAndEncodeTransaction(transaction *commandspb.Transaction) (string, error) {
   101  	pb, err := proto.Marshal(transaction)
   102  	if err != nil {
   103  		return "", fmt.Errorf("error when attempting to marshal Transaction struct back to a proto.\nerr: %w", err)
   104  	}
   105  
   106  	reEncodedTransaction := base64.StdEncoding.EncodeToString(pb)
   107  	logrus.Infof("successfully marshalled to proto and encoded")
   108  	return reEncodedTransaction, nil
   109  }