code.vegaprotocol.io/vega@v0.79.0/datanode/entities/data.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 entities 17 18 import ( 19 "encoding/hex" 20 "encoding/json" 21 "fmt" 22 "time" 23 24 dstypes "code.vegaprotocol.io/vega/core/datasource/common" 25 v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2" 26 vegapb "code.vegaprotocol.io/vega/protos/vega" 27 datapb "code.vegaprotocol.io/vega/protos/vega/data/v1" 28 ) 29 30 type ( 31 _Spec struct{} 32 SpecID = ID[_Spec] 33 ) 34 35 type ( 36 Signer []byte 37 Signers = []Signer 38 ) 39 40 type Property struct { 41 Name string 42 Value string 43 } 44 45 func SerializeSigners(signers []*dstypes.Signer) (Signers, error) { 46 if len(signers) > 0 { 47 sigList := Signers{} 48 49 for _, signer := range signers { 50 data, err := signer.Serialize() 51 if err != nil { 52 return nil, err 53 } 54 sigList = append(sigList, data) 55 } 56 57 return sigList, nil 58 } 59 60 return Signers{}, nil 61 } 62 63 func DeserializeSigners(data Signers) []*dstypes.Signer { 64 if len(data) > 0 { 65 signers := []*dstypes.Signer{} 66 for _, s := range data { 67 signer := dstypes.DeserializeSigner(s) 68 signers = append(signers, signer) 69 } 70 71 return signers 72 } 73 74 return nil 75 } 76 77 type Data struct { 78 Signers Signers 79 Data []Property 80 MetaData []Property 81 MatchedSpecIds [][]byte // pgx automatically handles [][]byte to Postgres ByteaArray mappings 82 BroadcastAt time.Time 83 Error *string 84 TxHash TxHash 85 VegaTime time.Time 86 SeqNum uint64 87 } 88 89 type ExternalData struct { 90 Data *Data 91 } 92 93 func ExternalDataFromProto(data *datapb.ExternalData, txHash TxHash, vegaTime time.Time, seqNum uint64) (*ExternalData, error) { 94 properties := []Property{} 95 specIDs := [][]byte{} 96 signers := Signers{} 97 var metaDataProperties []Property 98 99 if data.Data != nil { 100 properties = make([]Property, 0, len(data.Data.Data)) 101 specIDs = make([][]byte, 0, len(data.Data.MatchedSpecIds)) 102 103 for _, property := range data.Data.Data { 104 properties = append(properties, Property{ 105 Name: property.Name, 106 Value: property.Value, 107 }) 108 } 109 110 if len(data.Data.MetaData) > 0 { 111 metaDataProperties = make([]Property, 0, len(data.Data.MetaData)) 112 113 for _, m := range data.Data.MetaData { 114 metaDataProperties = append(metaDataProperties, Property{ 115 Name: m.Name, 116 Value: m.Value, 117 }) 118 } 119 } 120 121 for _, specID := range data.Data.MatchedSpecIds { 122 id := SpecID(specID) 123 idBytes, err := id.Bytes() 124 if err != nil { 125 return nil, fmt.Errorf("cannot decode spec ID: %w", err) 126 } 127 specIDs = append(specIDs, idBytes) 128 } 129 130 var err error 131 signers, err = SerializeSigners(dstypes.SignersFromProto(data.Data.Signers)) 132 if err != nil { 133 return nil, err 134 } 135 } 136 137 return &ExternalData{ 138 Data: &Data{ 139 Signers: signers, 140 Data: properties, 141 MetaData: metaDataProperties, 142 MatchedSpecIds: specIDs, 143 BroadcastAt: NanosToPostgresTimestamp(data.Data.BroadcastAt), 144 Error: data.Data.Error, 145 TxHash: txHash, 146 VegaTime: vegaTime, 147 SeqNum: seqNum, 148 }, 149 }, nil 150 } 151 152 func (od *ExternalData) ToProto() *datapb.ExternalData { 153 properties := []*datapb.Property{} 154 specIDs := []string{} 155 signersAsProto := []*datapb.Signer{} 156 metaDataProperties := []*datapb.Property{} 157 158 if od.Data != nil { 159 if od.Data.Data != nil { 160 properties = make([]*datapb.Property, 0, len(od.Data.Data)) 161 specIDs = make([]string, 0, len(od.Data.MatchedSpecIds)) 162 metaDataProperties = make([]*datapb.Property, 0, len(od.Data.MetaData)) 163 164 for _, prop := range od.Data.Data { 165 properties = append(properties, &datapb.Property{ 166 Name: prop.Name, 167 Value: prop.Value, 168 }) 169 } 170 171 for _, m := range od.Data.MetaData { 172 metaDataProperties = append(metaDataProperties, &datapb.Property{ 173 Name: m.Name, 174 Value: m.Value, 175 }) 176 } 177 178 for _, id := range od.Data.MatchedSpecIds { 179 hexID := hex.EncodeToString(id) 180 specIDs = append(specIDs, hexID) 181 } 182 } 183 184 signers := DeserializeSigners(od.Data.Signers) 185 signersAsProto = dstypes.SignersIntoProto(signers) 186 } 187 188 return &datapb.ExternalData{ 189 Data: &datapb.Data{ 190 Signers: signersAsProto, 191 Data: properties, 192 MetaData: metaDataProperties, 193 MatchedSpecIds: specIDs, 194 BroadcastAt: od.Data.BroadcastAt.UnixNano(), 195 Error: od.Data.Error, 196 }, 197 } 198 } 199 200 func (od ExternalData) ToOracleProto() *vegapb.OracleData { 201 return &vegapb.OracleData{ 202 ExternalData: od.ToProto(), 203 } 204 } 205 206 func (od ExternalData) Cursor() *Cursor { 207 return NewCursor(OracleDataCursor{ 208 VegaTime: od.Data.VegaTime, 209 Signers: od.Data.Signers, 210 }.String()) 211 } 212 213 func (od ExternalData) ToOracleProtoEdge(_ ...any) (*v2.OracleDataEdge, error) { 214 return &v2.OracleDataEdge{ 215 Node: od.ToOracleProto(), 216 Cursor: od.Cursor().Encode(), 217 }, nil 218 } 219 220 type ExternalDataCursor struct { 221 VegaTime time.Time `json:"vegaTime"` 222 Signers Signers `json:"signers"` 223 } 224 225 func (c ExternalDataCursor) String() string { 226 bs, err := json.Marshal(c) 227 if err != nil { 228 // This really shouldn't happen. 229 panic(fmt.Errorf("couldn't marshal oracle data cursor: %w", err)) 230 } 231 232 return string(bs) 233 } 234 235 func (c *ExternalDataCursor) Parse(cursorString string) error { 236 if cursorString == "" { 237 return nil 238 } 239 240 return json.Unmarshal([]byte(cursorString), c) 241 } 242 243 type Condition struct { 244 Operator datapb.Condition_Operator 245 Value string 246 } 247 248 func (c Condition) ToProto() *datapb.Condition { 249 return &datapb.Condition{ 250 Operator: c.Operator, 251 Value: c.Value, 252 } 253 } 254 255 func ConditionFromProto(protoCondition *datapb.Condition) Condition { 256 return Condition{ 257 Operator: protoCondition.Operator, 258 Value: protoCondition.Value, 259 } 260 } 261 262 type PropertyKey struct { 263 Name string `json:"name"` 264 Type datapb.PropertyKey_Type 265 DecimalPlaces *uint64 `json:"number_decimal_places,omitempty"` 266 } 267 268 type Filter struct { 269 Key PropertyKey `json:"key"` 270 Conditions []Condition `json:"conditions"` 271 } 272 273 func (f Filter) ToProto() *datapb.Filter { 274 conditions := make([]*datapb.Condition, 0, len(f.Conditions)) 275 for _, condition := range f.Conditions { 276 conditions = append(conditions, condition.ToProto()) 277 } 278 279 var ndp *uint64 280 if f.Key.DecimalPlaces != nil { 281 v := *f.Key.DecimalPlaces 282 ndp = &v 283 } 284 285 return &datapb.Filter{ 286 Key: &datapb.PropertyKey{ 287 Name: f.Key.Name, 288 Type: f.Key.Type, 289 NumberDecimalPlaces: ndp, 290 }, 291 Conditions: conditions, 292 } 293 } 294 295 func FiltersFromProto(filters []*datapb.Filter) []Filter { 296 if len(filters) == 0 { 297 return []Filter{} 298 } 299 300 results := make([]Filter, 0, len(filters)) 301 for _, filter := range filters { 302 conditions := make([]Condition, 0, len(filter.Conditions)) 303 304 for _, condition := range filter.Conditions { 305 conditions = append(conditions, Condition{ 306 Operator: condition.Operator, 307 Value: condition.Value, 308 }) 309 } 310 311 var ndp *uint64 312 if filter.Key.NumberDecimalPlaces != nil { 313 v := *filter.Key.NumberDecimalPlaces 314 ndp = &v 315 } 316 results = append(results, Filter{ 317 Key: PropertyKey{ 318 Name: filter.Key.Name, 319 Type: filter.Key.Type, 320 DecimalPlaces: ndp, 321 }, 322 Conditions: conditions, 323 }) 324 } 325 326 return results 327 }