code.vegaprotocol.io/vega@v0.79.0/commands/batch_proposal_submission.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
    17  
    18  import (
    19  	"errors"
    20  	"strings"
    21  
    22  	protoTypes "code.vegaprotocol.io/vega/protos/vega"
    23  	vegapb "code.vegaprotocol.io/vega/protos/vega"
    24  	commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
    25  )
    26  
    27  func CheckBatchProposalSubmission(cmd *commandspb.BatchProposalSubmission) error {
    28  	return checkBatchProposalSubmission(cmd).ErrorOrNil()
    29  }
    30  
    31  func checkBatchProposalSubmission(cmd *commandspb.BatchProposalSubmission) Errors {
    32  	errs := NewErrors()
    33  
    34  	if cmd == nil {
    35  		return errs.FinalAddForProperty("batch_proposal_submission", ErrIsRequired)
    36  	}
    37  
    38  	if len(cmd.Reference) > ReferenceMaxLen {
    39  		errs.AddForProperty("batch_proposal_submission.reference", ErrReferenceTooLong)
    40  	}
    41  
    42  	if cmd.Rationale == nil {
    43  		errs.AddForProperty("batch_proposal_submission.rationale", ErrIsRequired)
    44  	} else {
    45  		if cmd.Rationale != nil {
    46  			if len(strings.Trim(cmd.Rationale.Description, " \n\r\t")) == 0 {
    47  				errs.AddForProperty("batch_proposal_submission.rationale.description", ErrIsRequired)
    48  			} else if len(cmd.Rationale.Description) > 20000 {
    49  				errs.AddForProperty("batch_proposal_submission.rationale.description", ErrMustNotExceed20000Chars)
    50  			}
    51  			if len(strings.Trim(cmd.Rationale.Title, " \n\r\t")) == 0 {
    52  				errs.AddForProperty("batch_proposal_submission.rationale.title", ErrIsRequired)
    53  			} else if len(cmd.Rationale.Title) > 100 {
    54  				errs.AddForProperty("batch_proposal_submission.rationale.title", ErrMustBeLessThan100Chars)
    55  			}
    56  		}
    57  	}
    58  
    59  	if cmd.Terms == nil {
    60  		return errs.FinalAddForProperty("batch_proposal_submission.terms", ErrIsRequired)
    61  	}
    62  
    63  	if len(cmd.Terms.Changes) == 0 {
    64  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes", ErrIsRequired)
    65  	}
    66  
    67  	if len(cmd.Terms.Changes) > 250 {
    68  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes", ErrMustBeAtMost250)
    69  	}
    70  
    71  	if cmd.Terms.ClosingTimestamp <= 0 {
    72  		errs.AddForProperty("batch_proposal_submission.terms.closing_timestamp", ErrMustBePositive)
    73  	}
    74  
    75  	for _, batchChange := range cmd.Terms.Changes {
    76  		// check for enactment timestamp
    77  		switch batchChange.Change.(type) {
    78  		case *protoTypes.BatchProposalTermsChange_NewFreeform:
    79  			if batchChange.EnactmentTimestamp != 0 {
    80  				errs.AddForProperty("batch_proposal_submission.terms.enactment_timestamp", ErrIsNotSupported)
    81  			}
    82  		default:
    83  			if batchChange.EnactmentTimestamp <= 0 {
    84  				errs.AddForProperty("batch_proposal_submission.terms.enactment_timestamp", ErrMustBePositive)
    85  			}
    86  
    87  			if cmd.Terms.ClosingTimestamp > batchChange.EnactmentTimestamp {
    88  				errs.AddForProperty("batch_proposal_submission.terms.closing_timestamp",
    89  					errors.New("cannot be after enactment time"),
    90  				)
    91  			}
    92  		}
    93  
    94  		errs.Merge(checkBatchProposalChanges(batchChange))
    95  	}
    96  
    97  	return errs
    98  }
    99  
   100  func checkBatchProposalChanges(terms *protoTypes.BatchProposalTermsChange) Errors {
   101  	errs := NewErrors()
   102  
   103  	if terms.Change == nil {
   104  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes", ErrIsRequired)
   105  	}
   106  
   107  	switch c := terms.Change.(type) {
   108  	case *protoTypes.BatchProposalTermsChange_NewMarket:
   109  		errs.Merge(checkNewMarketBatchChanges(c))
   110  	case *protoTypes.BatchProposalTermsChange_UpdateMarket:
   111  		errs.Merge(checkUpdateMarketBatchChanges(c))
   112  	case *protoTypes.BatchProposalTermsChange_NewSpotMarket:
   113  		errs.Merge(checkNewSpotMarketBatchChanges(c))
   114  	case *protoTypes.BatchProposalTermsChange_UpdateSpotMarket:
   115  		errs.Merge(checkUpdateSpotMarketBatchChanges(c))
   116  	case *protoTypes.BatchProposalTermsChange_UpdateNetworkParameter:
   117  		errs.Merge(checkNetworkParameterUpdateBatchChanges(c))
   118  	case *protoTypes.BatchProposalTermsChange_UpdateAsset:
   119  		errs.Merge(checkUpdateAssetBatchChanges(c))
   120  	case *protoTypes.BatchProposalTermsChange_NewAsset:
   121  		errs.Merge(checkNewAssetBatchChanges(c))
   122  	case *protoTypes.BatchProposalTermsChange_NewFreeform:
   123  		errs.Merge(checkNewFreeformBatchChanges(c))
   124  	case *protoTypes.BatchProposalTermsChange_NewTransfer:
   125  		errs.Merge(checkNewTransferBatchChanges(c))
   126  	case *protoTypes.BatchProposalTermsChange_CancelTransfer:
   127  		errs.Merge(checkCancelTransferBatchChanges(c))
   128  	case *protoTypes.BatchProposalTermsChange_UpdateMarketState:
   129  		errs.Merge(checkMarketUpdateStateBatch(c))
   130  	case *protoTypes.BatchProposalTermsChange_UpdateReferralProgram:
   131  		errs.Merge(checkUpdateReferralProgramBatch(c, terms.EnactmentTimestamp))
   132  	case *protoTypes.BatchProposalTermsChange_UpdateVolumeDiscountProgram:
   133  		errs.Merge(checkVolumeDiscountProgramBatch(c, terms.EnactmentTimestamp))
   134  	default:
   135  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes", ErrIsNotValid)
   136  	}
   137  
   138  	return errs
   139  }
   140  
   141  func checkNewMarketBatchChanges(change *protoTypes.BatchProposalTermsChange_NewMarket) Errors {
   142  	errs := NewErrors()
   143  
   144  	if change.NewMarket == nil {
   145  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.new_market", ErrIsRequired)
   146  	}
   147  
   148  	if change.NewMarket.Changes == nil {
   149  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.new_market.changes", ErrIsRequired)
   150  	}
   151  
   152  	return checkNewMarketChangesConfiguration(change.NewMarket.Changes).AddPrefix("batch_proposal_submission.terms.changes.")
   153  }
   154  
   155  func checkUpdateMarketBatchChanges(change *protoTypes.BatchProposalTermsChange_UpdateMarket) Errors {
   156  	errs := NewErrors()
   157  
   158  	if change.UpdateMarket == nil {
   159  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.update_market", ErrIsRequired)
   160  	}
   161  
   162  	return checkUpdateMarket(change.UpdateMarket).AddPrefix("batch_proposal_submission.terms.changes.")
   163  }
   164  
   165  func checkNewSpotMarketBatchChanges(change *protoTypes.BatchProposalTermsChange_NewSpotMarket) Errors {
   166  	errs := NewErrors()
   167  
   168  	if change.NewSpotMarket == nil {
   169  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.new_spot_market", ErrIsRequired)
   170  	}
   171  
   172  	if change.NewSpotMarket.Changes == nil {
   173  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.new_spot_market.changes", ErrIsRequired)
   174  	}
   175  
   176  	return checkNewSpotMarketConfiguration(change.NewSpotMarket.Changes).AddPrefix("batch_proposal_submission.terms.changes.")
   177  }
   178  
   179  func checkUpdateSpotMarketBatchChanges(change *protoTypes.BatchProposalTermsChange_UpdateSpotMarket) Errors {
   180  	errs := NewErrors()
   181  
   182  	if change.UpdateSpotMarket == nil {
   183  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.update_spot_market", ErrIsRequired)
   184  	}
   185  
   186  	return checkUpdateSpotMarket(change.UpdateSpotMarket).AddPrefix("batch_proposal_submission.terms.changes.")
   187  }
   188  
   189  func checkNetworkParameterUpdateBatchChanges(change *protoTypes.BatchProposalTermsChange_UpdateNetworkParameter) Errors {
   190  	errs := NewErrors()
   191  
   192  	if change.UpdateNetworkParameter == nil {
   193  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.update_network_parameter", ErrIsRequired)
   194  	}
   195  
   196  	if change.UpdateNetworkParameter.Changes == nil {
   197  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.update_network_parameter.changes", ErrIsRequired)
   198  	}
   199  
   200  	return checkNetworkParameterUpdate(change.UpdateNetworkParameter.Changes).AddPrefix("batch_proposal_submission.terms.changes.")
   201  }
   202  
   203  func checkUpdateAssetBatchChanges(change *protoTypes.BatchProposalTermsChange_UpdateAsset) Errors {
   204  	errs := NewErrors()
   205  
   206  	if change.UpdateAsset == nil {
   207  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.update_asset", ErrIsRequired)
   208  	}
   209  
   210  	return checkUpdateAsset(change.UpdateAsset).AddPrefix("batch_proposal_submission.terms.changes.")
   211  }
   212  
   213  func checkNewAssetBatchChanges(change *protoTypes.BatchProposalTermsChange_NewAsset) Errors {
   214  	errs := NewErrors()
   215  
   216  	if change.NewAsset == nil {
   217  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.new_asset", ErrIsRequired)
   218  	}
   219  
   220  	return checkBatchNewAssetChanges(change).AddPrefix("batch_proposal_submission.terms.changes.")
   221  }
   222  
   223  func checkNewFreeformBatchChanges(change *protoTypes.BatchProposalTermsChange_NewFreeform) Errors {
   224  	errs := NewErrors()
   225  
   226  	if change.NewFreeform == nil {
   227  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.new_freeform", ErrIsRequired)
   228  	}
   229  	return errs
   230  }
   231  
   232  func checkNewTransferBatchChanges(change *protoTypes.BatchProposalTermsChange_NewTransfer) Errors {
   233  	errs := NewErrors()
   234  	if change.NewTransfer == nil {
   235  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.new_transfer", ErrIsRequired)
   236  	}
   237  
   238  	if change.NewTransfer.Changes == nil {
   239  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.new_transfer.changes", ErrIsRequired)
   240  	}
   241  
   242  	return checkNewTransferConfiguration(change.NewTransfer.Changes).AddPrefix("batch_proposal_submission.terms.changes")
   243  }
   244  
   245  func checkCancelTransferBatchChanges(change *protoTypes.BatchProposalTermsChange_CancelTransfer) Errors {
   246  	errs := NewErrors()
   247  	if change.CancelTransfer == nil {
   248  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.cancel_transfer", ErrIsRequired)
   249  	}
   250  
   251  	if change.CancelTransfer.Changes == nil {
   252  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.cancel_transfer.changes", ErrIsRequired)
   253  	}
   254  
   255  	changes := change.CancelTransfer.Changes
   256  	if len(changes.TransferId) == 0 {
   257  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.cancel_transfer.changes.transferId", ErrIsRequired)
   258  	}
   259  	return errs
   260  }
   261  
   262  func checkMarketUpdateStateBatch(change *protoTypes.BatchProposalTermsChange_UpdateMarketState) Errors {
   263  	errs := NewErrors()
   264  	if change.UpdateMarketState == nil {
   265  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.update_market_state", ErrIsRequired)
   266  	}
   267  	if change.UpdateMarketState.Changes == nil {
   268  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.update_market_state.changes", ErrIsRequired)
   269  	}
   270  	return checkMarketUpdateConfiguration(change.UpdateMarketState.Changes).AddPrefix("batch_proposal_submission.terms.changes.")
   271  }
   272  
   273  func checkUpdateReferralProgramBatch(change *vegapb.BatchProposalTermsChange_UpdateReferralProgram, enactmentTimestamp int64) Errors {
   274  	errs := NewErrors()
   275  	if change.UpdateReferralProgram == nil {
   276  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.update_referral_program", ErrIsRequired)
   277  	}
   278  	if change.UpdateReferralProgram.Changes == nil {
   279  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.update_referral_program.changes", ErrIsRequired)
   280  	}
   281  
   282  	return checkReferralProgramChanges(change.UpdateReferralProgram.Changes, enactmentTimestamp).
   283  		AddPrefix("batch_proposal_submission.terms.changes.")
   284  }
   285  
   286  func checkVolumeDiscountProgramBatch(change *vegapb.BatchProposalTermsChange_UpdateVolumeDiscountProgram, enactmentTimestamp int64) Errors {
   287  	errs := NewErrors()
   288  	if change.UpdateVolumeDiscountProgram == nil {
   289  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.update_volume_discount_program", ErrIsRequired)
   290  	}
   291  	if change.UpdateVolumeDiscountProgram.Changes == nil {
   292  		return errs.FinalAddForProperty("batch_proposal_submission.terms.changes.update_volume_discount_program.changes", ErrIsRequired)
   293  	}
   294  
   295  	return checkVolumeDiscountProgramChanges(change.UpdateVolumeDiscountProgram.Changes, enactmentTimestamp).
   296  		AddPrefix("batch_proposal_submission.terms.changes.")
   297  }