code.vegaprotocol.io/vega@v0.79.0/core/events/transaction_result.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 events 17 18 import ( 19 "context" 20 "fmt" 21 "sort" 22 23 commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1" 24 eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1" 25 ) 26 27 type TransactionResult struct { 28 *Base 29 evt *eventspb.TransactionResult 30 } 31 32 func (tr *TransactionResult) PartyID() string { 33 return tr.evt.PartyId 34 } 35 36 func (tr *TransactionResult) Status() bool { 37 return tr.evt.Status 38 } 39 40 func (tr *TransactionResult) Hash() string { 41 return tr.evt.Hash 42 } 43 44 func NewTransactionResultEventSuccess( 45 ctx context.Context, 46 hash, party string, 47 tx interface{}, 48 ) *TransactionResult { 49 evt := &TransactionResult{ 50 Base: newBase(ctx, TransactionResultEvent), 51 evt: &eventspb.TransactionResult{ 52 PartyId: party, 53 Hash: hash, 54 Status: true, 55 StatusDetail: eventspb.TransactionResult_STATUS_SUCCESS, 56 }, 57 } 58 59 return evt.setTx(tx) 60 } 61 62 type RawErrors interface { 63 GetRawErrors() map[string][]error 64 } 65 66 func makeFailureDetails(err error) *eventspb.TransactionResult_FailureDetails { 67 if rawErr, isRawErr := err.(RawErrors); isRawErr { 68 keyErrors := []*eventspb.TransactionResult_KeyErrors{} 69 for k, v := range rawErr.GetRawErrors() { 70 e := &eventspb.TransactionResult_KeyErrors{ 71 Key: k, 72 } 73 74 for _, ve := range v { 75 e.Errors = append(e.Errors, ve.Error()) 76 } 77 78 keyErrors = append(keyErrors, e) 79 } 80 81 sort.Slice(keyErrors, func(i, j int) bool { 82 return keyErrors[i].Key < keyErrors[j].Key 83 }) 84 85 return &eventspb.TransactionResult_FailureDetails{ 86 Errors: keyErrors, 87 } 88 } 89 90 return &eventspb.TransactionResult_FailureDetails{ 91 Error: err.Error(), 92 } 93 } 94 95 type PartialError interface { 96 IsPartial() bool 97 } 98 99 func getErrorStatus(err error) eventspb.TransactionResult_Status { 100 if partialErr, isPartialErr := err.(PartialError); isPartialErr { 101 if partialErr.IsPartial() { 102 return eventspb.TransactionResult_STATUS_PARTIAL_SUCCESS 103 } 104 } 105 106 return eventspb.TransactionResult_STATUS_FAILURE 107 } 108 109 func NewTransactionResultEventFailure( 110 ctx context.Context, 111 hash, party string, 112 err error, 113 tx interface{}, 114 ) *TransactionResult { 115 evt := &TransactionResult{ 116 Base: newBase(ctx, TransactionResultEvent), 117 evt: &eventspb.TransactionResult{ 118 PartyId: party, 119 Hash: hash, 120 Status: false, 121 StatusDetail: getErrorStatus(err), 122 Extra: &eventspb.TransactionResult_Failure{ 123 Failure: makeFailureDetails(err), 124 }, 125 }, 126 } 127 128 return evt.setTx(tx) 129 } 130 131 func (t *TransactionResult) setTx(tx interface{}) *TransactionResult { 132 switch tv := tx.(type) { 133 case *commandspb.DelayedTransactionsWrapper: 134 break 135 case *commandspb.OrderSubmission: 136 t.evt.Transaction = &eventspb.TransactionResult_OrderSubmission{ 137 OrderSubmission: tv, 138 } 139 case *commandspb.OrderCancellation: 140 t.evt.Transaction = &eventspb.TransactionResult_OrderCancellation{ 141 OrderCancellation: tv, 142 } 143 case *commandspb.OrderAmendment: 144 t.evt.Transaction = &eventspb.TransactionResult_OrderAmendment{ 145 OrderAmendment: tv, 146 } 147 case *commandspb.VoteSubmission: 148 t.evt.Transaction = &eventspb.TransactionResult_VoteSubmission{ 149 VoteSubmission: tv, 150 } 151 case *commandspb.WithdrawSubmission: 152 t.evt.Transaction = &eventspb.TransactionResult_WithdrawSubmission{ 153 WithdrawSubmission: tv, 154 } 155 case *commandspb.LiquidityProvisionSubmission: 156 t.evt.Transaction = &eventspb.TransactionResult_LiquidityProvisionSubmission{ 157 LiquidityProvisionSubmission: tv, 158 } 159 case *commandspb.LiquidityProvisionCancellation: 160 t.evt.Transaction = &eventspb.TransactionResult_LiquidityProvisionCancellation{ 161 LiquidityProvisionCancellation: tv, 162 } 163 case *commandspb.LiquidityProvisionAmendment: 164 t.evt.Transaction = &eventspb.TransactionResult_LiquidityProvisionAmendment{ 165 LiquidityProvisionAmendment: tv, 166 } 167 case *commandspb.ProposalSubmission: 168 t.evt.Transaction = &eventspb.TransactionResult_Proposal{ 169 Proposal: tv, 170 } 171 case *commandspb.DelegateSubmission: 172 t.evt.Transaction = &eventspb.TransactionResult_DelegateSubmission{ 173 DelegateSubmission: tv, 174 } 175 case *commandspb.UndelegateSubmission: 176 t.evt.Transaction = &eventspb.TransactionResult_UndelegateSubmission{ 177 UndelegateSubmission: tv, 178 } 179 case *commandspb.Transfer: 180 t.evt.Transaction = &eventspb.TransactionResult_Transfer{ 181 Transfer: tv, 182 } 183 case *commandspb.CancelTransfer: 184 t.evt.Transaction = &eventspb.TransactionResult_CancelTransfer{ 185 CancelTransfer: tv, 186 } 187 case *commandspb.AnnounceNode: 188 t.evt.Transaction = &eventspb.TransactionResult_AnnounceNode{ 189 AnnounceNode: tv, 190 } 191 case *commandspb.OracleDataSubmission: 192 t.evt.Transaction = &eventspb.TransactionResult_OracleDataSubmission{ 193 OracleDataSubmission: tv, 194 } 195 case *commandspb.ProtocolUpgradeProposal: 196 t.evt.Transaction = &eventspb.TransactionResult_ProtocolUpgradeProposal{ 197 ProtocolUpgradeProposal: tv, 198 } 199 case *commandspb.IssueSignatures: 200 t.evt.Transaction = &eventspb.TransactionResult_IssueSignatures{ 201 IssueSignatures: tv, 202 } 203 case *commandspb.BatchMarketInstructions: 204 t.evt.Transaction = &eventspb.TransactionResult_BatchMarketInstructions{ 205 BatchMarketInstructions: tv, 206 } 207 case *commandspb.KeyRotateSubmission: 208 t.evt.Transaction = &eventspb.TransactionResult_KeyRotateSubmission{ 209 KeyRotateSubmission: tv, 210 } 211 case *commandspb.EthereumKeyRotateSubmission: 212 t.evt.Transaction = &eventspb.TransactionResult_EthereumKeyRotateSubmission{ 213 EthereumKeyRotateSubmission: tv, 214 } 215 case *commandspb.StopOrdersSubmission: 216 t.evt.Transaction = &eventspb.TransactionResult_StopOrdersSubmission{ 217 StopOrdersSubmission: tv, 218 } 219 case *commandspb.StopOrdersCancellation: 220 t.evt.Transaction = &eventspb.TransactionResult_StopOrdersCancellation{ 221 StopOrdersCancellation: tv, 222 } 223 case *commandspb.CreateReferralSet: 224 t.evt.Transaction = &eventspb.TransactionResult_CreateReferralSet{ 225 CreateReferralSet: tv, 226 } 227 case *commandspb.UpdateReferralSet: 228 t.evt.Transaction = &eventspb.TransactionResult_UpdateReferralSet{ 229 UpdateReferralSet: tv, 230 } 231 case *commandspb.ApplyReferralCode: 232 t.evt.Transaction = &eventspb.TransactionResult_ApplyReferralCode{ 233 ApplyReferralCode: tv, 234 } 235 case *commandspb.UpdateMarginMode: 236 t.evt.Transaction = &eventspb.TransactionResult_UpdateMarginMode{ 237 UpdateMarginMode: tv, 238 } 239 case *commandspb.JoinTeam: 240 t.evt.Transaction = &eventspb.TransactionResult_JoinTeam{ 241 JoinTeam: tv, 242 } 243 case *commandspb.BatchProposalSubmission: 244 t.evt.Transaction = &eventspb.TransactionResult_BatchProposal{ 245 BatchProposal: tv, 246 } 247 case *commandspb.UpdatePartyProfile: 248 t.evt.Transaction = &eventspb.TransactionResult_UpdatePartyProfile{ 249 UpdatePartyProfile: tv, 250 } 251 case *commandspb.SubmitAMM: 252 t.evt.Transaction = &eventspb.TransactionResult_SubmitAmm{ 253 SubmitAmm: tv, 254 } 255 case *commandspb.AmendAMM: 256 t.evt.Transaction = &eventspb.TransactionResult_AmendAmm{ 257 AmendAmm: tv, 258 } 259 case *commandspb.CancelAMM: 260 t.evt.Transaction = &eventspb.TransactionResult_CancelAmm{ 261 CancelAmm: tv, 262 } 263 default: 264 panic(fmt.Sprintf("unsupported command %T", tv)) 265 } 266 267 return t 268 } 269 270 func (t TransactionResult) IsParty(id string) bool { 271 return t.evt.PartyId == id 272 } 273 274 func (t TransactionResult) Proto() eventspb.TransactionResult { 275 return *t.evt 276 } 277 278 func (t TransactionResult) TransactionResult() TransactionResult { 279 return t 280 } 281 282 func (t TransactionResult) StreamMessage() *eventspb.BusEvent { 283 busEvent := newBusEventFromBase(t.Base) 284 busEvent.Event = &eventspb.BusEvent_TransactionResult{ 285 TransactionResult: t.evt, 286 } 287 288 return busEvent 289 } 290 291 func TransactionResultEventFromStream(ctx context.Context, be *eventspb.BusEvent) *TransactionResult { 292 return &TransactionResult{ 293 Base: newBaseFromBusEvent(ctx, TransactionResultEvent, be), 294 evt: be.GetTransactionResult(), 295 } 296 }