code.vegaprotocol.io/vega@v0.79.0/core/integration/steps/parties_submit_liquidity_provision.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 steps 17 18 import ( 19 "context" 20 "encoding/hex" 21 "errors" 22 "fmt" 23 "sort" 24 25 "code.vegaprotocol.io/vega/core/types" 26 "code.vegaprotocol.io/vega/libs/crypto" 27 "code.vegaprotocol.io/vega/libs/num" 28 29 "github.com/cucumber/godog" 30 ) 31 32 type LPUpdate struct { 33 MarketID string 34 CommitmentAmount *num.Uint 35 Fee num.Decimal 36 Reference string 37 LpType string 38 Err string 39 } 40 41 func PartyCancelsTheirLiquidityProvision(exec Execution, marketID, party string) error { 42 cancel := types.LiquidityProvisionCancellation{ 43 MarketID: marketID, 44 } 45 if err := exec.CancelLiquidityProvision(context.Background(), &cancel, party); err != nil { 46 return errCancelLiquidityProvision(party, marketID, err) 47 } 48 return nil 49 } 50 51 func PartiesSubmitLiquidityProvision(exec Execution, table *godog.Table) error { 52 lps := map[string]*LPUpdate{} 53 parties := map[string]string{} 54 keys := []string{} 55 56 var errRow ErroneousRow 57 for _, r := range parseSubmitLiquidityProvisionTable(table) { 58 row := submitLiquidityProvisionRow{row: r} 59 if errRow == nil || row.ExpectError() { 60 errRow = row 61 } 62 id := row.ID() 63 ref := id 64 65 if _, ok := lps[id]; !ok { 66 lp := &LPUpdate{ 67 MarketID: row.MarketID(), 68 CommitmentAmount: row.CommitmentAmount(), 69 Fee: row.Fee(), 70 Reference: ref, 71 LpType: row.LpType(), 72 Err: row.Error(), 73 } 74 parties[id] = row.Party() 75 lps[id] = lp 76 keys = append(keys, id) 77 } 78 } 79 // ensure we always submit in the same order 80 sort.Strings(keys) 81 for _, id := range keys { 82 lp, ok := lps[id] 83 if !ok { 84 return errors.New("LP not found") 85 } 86 party, ok := parties[id] 87 if !ok { 88 return errors.New("party for LP not found") 89 } 90 91 if lp.LpType == "amendment" { 92 lpa := &types.LiquidityProvisionAmendment{ 93 MarketID: lp.MarketID, 94 CommitmentAmount: lp.CommitmentAmount, 95 Fee: lp.Fee, 96 Reference: lp.Reference, 97 } 98 99 err := exec.AmendLiquidityProvision(context.Background(), lpa, party) 100 if ceerr := checkExpectedError(errRow, err, errAmendingLiquidityProvision(lpa, party, err)); ceerr != nil { 101 return ceerr 102 } 103 } else if lp.LpType == "submission" { 104 sub := &types.LiquidityProvisionSubmission{ 105 MarketID: lp.MarketID, 106 CommitmentAmount: lp.CommitmentAmount, 107 Fee: lp.Fee, 108 Reference: lp.Reference, 109 } 110 deterministicID := hex.EncodeToString(crypto.Hash([]byte(id + party + lp.MarketID))) 111 err := exec.SubmitLiquidityProvision(context.Background(), sub, party, id, deterministicID) 112 if ceerr := checkExpectedError(errRow, err, errSubmittingLiquidityProvision(sub, party, id, err)); ceerr != nil { 113 return ceerr 114 } 115 } else if lp.LpType == "cancellation" { 116 cancel := types.LiquidityProvisionCancellation{ 117 MarketID: lp.MarketID, 118 } 119 err := exec.CancelLiquidityProvision(context.Background(), &cancel, party) 120 if ceerr := checkExpectedError(errRow, err, errCancelLiquidityProvision(party, lp.MarketID, err)); ceerr != nil { 121 return ceerr 122 } 123 } 124 } 125 return nil 126 } 127 128 func errSubmittingLiquidityProvision(lp *types.LiquidityProvisionSubmission, party, id string, err error) error { 129 return fmt.Errorf("failed to submit [%v] for party %s and id %s: %v", lp, party, id, err) 130 } 131 132 func errCancelLiquidityProvision(party, market string, err error) error { 133 return fmt.Errorf("failed to cancel LP for party %s on market %s: %v", party, market, err) 134 } 135 136 func errAmendingLiquidityProvision(lp *types.LiquidityProvisionAmendment, party string, err error) error { 137 return fmt.Errorf("failed to amend [%v] for party %s : %v", lp, party, err) 138 } 139 140 func parseSubmitLiquidityProvisionTable(table *godog.Table) []RowWrapper { 141 return StrictParseTable(table, []string{ 142 "id", 143 "party", 144 "market id", 145 "commitment amount", 146 "fee", 147 "lp type", 148 }, []string{ 149 "reference", 150 "error", 151 }) 152 } 153 154 type submitLiquidityProvisionRow struct { 155 row RowWrapper 156 } 157 158 func (r submitLiquidityProvisionRow) ID() string { 159 return r.row.MustStr("id") 160 } 161 162 func (r submitLiquidityProvisionRow) Party() string { 163 return r.row.MustStr("party") 164 } 165 166 func (r submitLiquidityProvisionRow) MarketID() string { 167 return r.row.MustStr("market id") 168 } 169 170 func (r submitLiquidityProvisionRow) Side() types.Side { 171 if len(r.row.Str("side")) == 0 { 172 return types.SideUnspecified 173 } 174 return r.row.MustSide("side") 175 } 176 177 func (r submitLiquidityProvisionRow) CommitmentAmount() *num.Uint { 178 return r.row.MustUint("commitment amount") 179 } 180 181 func (r submitLiquidityProvisionRow) Fee() num.Decimal { 182 return r.row.MustDecimal("fee") 183 } 184 185 func (r submitLiquidityProvisionRow) LpType() string { 186 return r.row.MustStr("lp type") 187 } 188 189 func (r submitLiquidityProvisionRow) Reference() string { 190 return r.row.Str("reference") 191 } 192 193 func (r submitLiquidityProvisionRow) Error() string { 194 return r.row.Str("error") 195 } 196 197 func (r submitLiquidityProvisionRow) ExpectError() bool { 198 return r.row.HasColumn("error") 199 }