code.vegaprotocol.io/vega@v0.79.0/core/integration/steps/the_following_transfers_should_happen.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 "fmt" 20 21 "code.vegaprotocol.io/vega/core/events" 22 "code.vegaprotocol.io/vega/core/integration/stubs" 23 vegapb "code.vegaprotocol.io/vega/protos/vega" 24 25 "github.com/cucumber/godog" 26 ) 27 28 func TheFollowingTransfersShouldHappen( 29 broker *stubs.BrokerStub, 30 exec Execution, 31 table *godog.Table, 32 ) error { 33 transfers := broker.GetTransfers(true) 34 35 for _, r := range parseTransferTable(table) { 36 row := transferRow{row: r} 37 if row.IsAMM() { 38 found := false 39 if id, ok := exec.GetAMMSubAccountID(row.From()); ok { 40 row.row.values["from"] = id 41 found = true 42 } 43 if id, ok := exec.GetAMMSubAccountID(row.To()); ok { 44 row.row.values["to"] = id 45 found = true 46 } 47 if !found { 48 return fmt.Errorf("no AMM aliases found for from (%s) or to (%s)", row.From(), row.To()) 49 } 50 } 51 52 matched, divergingAmounts := matchTransfers(transfers, row) 53 54 if matched { 55 continue 56 } 57 58 if len(divergingAmounts) == 0 { 59 return errMissingTransfer(row) 60 } 61 return errTransferFoundButNotRightAmount(row, divergingAmounts) 62 } 63 64 broker.ResetType(events.LedgerMovementsEvent) 65 66 return nil 67 } 68 69 func errTransferFoundButNotRightAmount(row transferRow, divergingAmounts []uint64) error { 70 return formatDiff( 71 fmt.Sprintf("invalid amount for transfer from %s to %s", row.FromAccountID(), row.ToAccountID()), 72 map[string]string{ 73 "amount": u64ToS(row.Amount()), 74 }, 75 map[string]string{ 76 "amount": u64SToS(divergingAmounts), 77 }, 78 ) 79 } 80 81 func errMissingTransfer(row transferRow) error { 82 return fmt.Errorf("missing transfers between %v and %v for amount %v", 83 row.FromAccountID(), row.ToAccountID(), row.Amount(), 84 ) 85 } 86 87 func matchTransfers(ledgerEntries []*vegapb.LedgerEntry, row transferRow) (bool, []uint64) { 88 divergingAmounts := []uint64{} 89 for _, transfer := range ledgerEntries { 90 if transfer.FromAccount.ID() == row.FromAccountID() && transfer.ToAccount.ID() == row.ToAccountID() { 91 if row.Type() != "" && transfer.Type != vegapb.TransferType(vegapb.TransferType_value[row.Type()]) { 92 continue 93 } 94 if stringToU64(transfer.Amount) == row.Amount() { 95 return true, nil 96 } 97 divergingAmounts = append(divergingAmounts, stringToU64(transfer.Amount)) 98 } 99 } 100 return false, divergingAmounts 101 } 102 103 func parseTransferTable(table *godog.Table) []RowWrapper { 104 return StrictParseTable(table, []string{ 105 "from", 106 "from account", 107 "to", 108 "to account", 109 "market id", 110 "amount", 111 "asset", 112 }, []string{ 113 "type", 114 "is amm", 115 }) 116 } 117 118 type transferRow struct { 119 row RowWrapper 120 } 121 122 func (r transferRow) From() string { 123 return r.row.MustStr("from") 124 } 125 126 func (r transferRow) FromAccount() vegapb.AccountType { 127 return r.row.MustAccount("from account") 128 } 129 130 func (r transferRow) FromAccountID() string { 131 return AccountID(r.MarketID(), r.From(), r.Asset(), r.FromAccount()) 132 } 133 134 func (r transferRow) To() string { 135 return r.row.MustStr("to") 136 } 137 138 func (r transferRow) Type() string { 139 return r.row.Str("type") 140 } 141 142 func (r transferRow) ToAccount() vegapb.AccountType { 143 return r.row.MustAccount("to account") 144 } 145 146 func (r transferRow) ToAccountID() string { 147 mID := r.MarketID() 148 ta := r.ToAccount() 149 if ta == vegapb.AccountType_ACCOUNT_TYPE_NETWORK_TREASURY { 150 mID = "" 151 } 152 return AccountID(mID, r.To(), r.Asset(), ta) 153 } 154 155 func (r transferRow) MarketID() string { 156 return r.row.MustStr("market id") 157 } 158 159 func (r transferRow) Amount() uint64 { 160 return r.row.MustU64("amount") 161 } 162 163 func (r transferRow) Asset() string { 164 return r.row.MustStr("asset") 165 } 166 167 func (r transferRow) IsAMM() bool { 168 if !r.row.HasColumn("is amm") { 169 return false 170 } 171 return r.row.MustBool("is amm") 172 }