code.vegaprotocol.io/vega@v0.79.0/core/datasource/common/data_signer.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 //lint:file-ignore ST1003 Ignore underscores in names, this is straigh copied from the proto package to ease introducing the domain types 17 18 package common 19 20 import ( 21 "encoding/hex" 22 "fmt" 23 "strings" 24 25 "code.vegaprotocol.io/vega/core/datasource/errors" 26 "code.vegaprotocol.io/vega/libs/stringer" 27 datapb "code.vegaprotocol.io/vega/protos/vega/data/v1" 28 ) 29 30 // PubKey. 31 type PubKey struct { 32 Key string 33 } 34 35 func (p PubKey) IntoProto() *datapb.PubKey { 36 return &datapb.PubKey{ 37 Key: p.Key, 38 } 39 } 40 41 func (p PubKey) String() string { 42 return fmt.Sprintf( 43 "pubKey(%s)", 44 p.Key, 45 ) 46 } 47 48 func (p PubKey) DeepClone() *PubKey { 49 return &PubKey{ 50 Key: p.Key, 51 } 52 } 53 54 type SignerPubKey struct { 55 PubKey *PubKey 56 } 57 58 func (s SignerPubKey) String() string { 59 return fmt.Sprintf( 60 "signerPubKey(%s)", 61 stringer.PtrToString(s.PubKey), 62 ) 63 } 64 65 func (s SignerPubKey) IntoProto() *datapb.Signer_PubKey { 66 pubKey := &datapb.PubKey{} 67 if s.PubKey != nil { 68 pubKey = s.PubKey.IntoProto() 69 } 70 71 return &datapb.Signer_PubKey{ 72 PubKey: pubKey, 73 } 74 } 75 76 func (s SignerPubKey) oneOfProto() interface{} { 77 return s.IntoProto() 78 } 79 80 func (s SignerPubKey) GetSignerType() SignerType { 81 return SignerTypePubKey 82 } 83 84 func (s SignerPubKey) DeepClone() signer { 85 if s.PubKey == nil { 86 return &SignerPubKey{} 87 } 88 return &SignerPubKey{ 89 PubKey: s.PubKey, 90 } 91 } 92 93 func (s SignerPubKey) IsEmpty() bool { 94 if s.PubKey == nil { 95 return true 96 } 97 return s.PubKey.Key == "" 98 } 99 100 func (s SignerPubKey) AsHex(prepend bool) (signer, error) { 101 if s.PubKey == nil { 102 return &s, errors.ErrSignerIsEmpty 103 } 104 105 if s.PubKey.Key == "" { 106 return nil, errors.ErrSignerIsEmpty 107 } 108 109 // Check if the content is already hex encoded 110 if strings.HasPrefix(s.PubKey.Key, "0x") { 111 return &s, nil 112 } 113 114 validHex, _ := isHex(s.PubKey.Key) 115 if validHex { 116 if prepend { 117 s.PubKey.Key = fmt.Sprintf("0x%s", s.PubKey.Key) 118 } 119 return &s, nil 120 } 121 122 // If the content is not a valid Hex - encode it 123 s.PubKey.Key = fmt.Sprintf("0x%s", hex.EncodeToString([]byte(s.PubKey.Key))) 124 return &s, nil 125 } 126 127 func (s SignerPubKey) AsString() (signer, error) { 128 if s.PubKey == nil { 129 return nil, errors.ErrSignerIsEmpty 130 } 131 132 // Check if the content is hex encoded 133 st := strings.TrimPrefix(s.PubKey.Key, "0x") 134 validHex, _ := isHex(st) 135 if validHex { 136 decoded, err := hex.DecodeString(st) 137 if err != nil { 138 return &s, fmt.Errorf("error decoding signer: %v", err) 139 } 140 141 s.PubKey.Key = string(decoded) 142 } 143 return &s, nil 144 } 145 146 func (s SignerPubKey) Serialize() []byte { 147 c := strings.TrimPrefix(s.PubKey.Key, "0x") 148 return append([]byte{byte(SignerPubKeyPrepend)}, []byte(c)...) 149 } 150 151 func DeserializePubKey(data []byte) *SignerPubKey { 152 return &SignerPubKey{ 153 PubKey: &PubKey{ 154 Key: string(data), 155 }, 156 } 157 } 158 159 func PubKeyFromProto(s *datapb.Signer_PubKey) *SignerPubKey { 160 var pubKey *PubKey 161 if s != nil { 162 if s.PubKey != nil { 163 pubKey = &PubKey{ 164 Key: s.PubKey.Key, 165 } 166 } 167 } 168 169 return &SignerPubKey{ 170 PubKey: pubKey, 171 } 172 } 173 174 // ETHAddress. 175 type ETHAddress struct { 176 Address string 177 } 178 179 func (e ETHAddress) IntoProto() *datapb.ETHAddress { 180 return &datapb.ETHAddress{ 181 Address: e.Address, 182 } 183 } 184 185 func (e ETHAddress) String() string { 186 return fmt.Sprintf( 187 "ethAddress(%s)", 188 e.Address, 189 ) 190 } 191 192 func (e ETHAddress) DeepClone() *ETHAddress { 193 return ÐAddress{ 194 Address: e.Address, 195 } 196 } 197 198 type SignerETHAddress struct { 199 ETHAddress *ETHAddress 200 } 201 202 func (s SignerETHAddress) String() string { 203 return fmt.Sprintf( 204 "signerETHAddress(%s)", 205 stringer.PtrToString(s.ETHAddress), 206 ) 207 } 208 209 func (s SignerETHAddress) IntoProto() *datapb.Signer_EthAddress { 210 ethAddress := &datapb.ETHAddress{} 211 if s.ETHAddress != nil { 212 ethAddress = s.ETHAddress.IntoProto() 213 } 214 215 return &datapb.Signer_EthAddress{ 216 EthAddress: ethAddress, 217 } 218 } 219 220 func (s SignerETHAddress) oneOfProto() interface{} { 221 return s.IntoProto() 222 } 223 224 func (s SignerETHAddress) GetSignerType() SignerType { 225 return SignerTypeEthAddress 226 } 227 228 func (s SignerETHAddress) DeepClone() signer { 229 if s.ETHAddress == nil { 230 return &SignerETHAddress{} 231 } 232 return &SignerETHAddress{ 233 ETHAddress: s.ETHAddress, 234 } 235 } 236 237 func (s SignerETHAddress) IsEmpty() bool { 238 if s.ETHAddress == nil { 239 return true 240 } 241 return s.ETHAddress.Address == "" 242 } 243 244 func (s SignerETHAddress) AsHex(prepend bool) (signer, error) { 245 if s.ETHAddress == nil { 246 return nil, errors.ErrSignerIsEmpty 247 } 248 249 if s.ETHAddress.Address == "" { 250 return nil, errors.ErrSignerIsEmpty 251 } 252 253 // Check if the content is already hex encoded 254 if strings.HasPrefix(s.ETHAddress.Address, "0x") { 255 return &s, nil 256 } 257 258 validHex, _ := isHex(s.ETHAddress.Address) 259 if validHex { 260 if prepend { 261 s.ETHAddress.Address = fmt.Sprintf("0x%s", s.ETHAddress.Address) 262 } 263 return &s, nil 264 } 265 266 s.ETHAddress.Address = fmt.Sprintf("0x%s", hex.EncodeToString([]byte(s.ETHAddress.Address))) 267 return &s, nil 268 } 269 270 func (s SignerETHAddress) AsString() (signer, error) { 271 if s.ETHAddress == nil { 272 return nil, errors.ErrSignerIsEmpty 273 } 274 275 // Check if the content is hex encoded 276 st := strings.TrimPrefix(s.ETHAddress.Address, "0x") 277 validHex, _ := isHex(st) 278 if validHex { 279 decoded, err := hex.DecodeString(st) 280 if err != nil { 281 return &s, fmt.Errorf("error decoding signer: %v", err) 282 } 283 284 s.ETHAddress.Address = string(decoded) 285 } 286 return &s, nil 287 } 288 289 func (s SignerETHAddress) Serialize() []byte { 290 c := strings.TrimPrefix(s.ETHAddress.Address, "0x") 291 return append([]byte{byte(ETHAddressPrepend)}, []byte(c)...) 292 } 293 294 func DeserializeETHAddress(data []byte) *SignerETHAddress { 295 return &SignerETHAddress{ 296 ETHAddress: ÐAddress{ 297 Address: "0x" + string(data), 298 }, 299 } 300 } 301 302 func ETHAddressFromProto(s *datapb.Signer_EthAddress) *SignerETHAddress { 303 var ethAddress *ETHAddress 304 if s != nil { 305 if s.EthAddress != nil { 306 ethAddress = ÐAddress{ 307 Address: s.EthAddress.Address, 308 } 309 } 310 } 311 312 return &SignerETHAddress{ 313 ETHAddress: ethAddress, 314 } 315 } 316 317 type SignerType int 318 319 const ( 320 SignerTypeUnspecified SignerType = iota 321 SignerTypePubKey 322 SignerTypeEthAddress 323 ) 324 325 type Signer struct { 326 Signer signer 327 } 328 329 func (s Signer) oneOfProto() interface{} { 330 return s.IntoProto() 331 } 332 333 // IntoProto will always return a `datapb.Signer` that needs to be checked 334 // if it has any content afterwards. 335 func (s Signer) IntoProto() *datapb.Signer { 336 signer := &datapb.Signer{} 337 if s.Signer != nil { 338 sig := s.Signer.oneOfProto() 339 340 switch tp := sig.(type) { 341 case *datapb.Signer_PubKey: 342 signer.Signer = tp 343 case *datapb.Signer_EthAddress: 344 signer.Signer = tp 345 } 346 } 347 348 return signer 349 } 350 351 func (s Signer) DeepClone() *Signer { 352 cpy := s 353 cpy.Signer = s.Signer.DeepClone() 354 return &cpy 355 } 356 357 func (s Signer) String() string { 358 return stringer.ObjToString(s.Signer) 359 } 360 361 func (s Signer) IsEmpty() bool { 362 if s.Signer != nil { 363 return s.Signer.IsEmpty() 364 } 365 return true 366 } 367 368 func (s Signer) GetSignerPubKey() *PubKey { 369 if s.Signer != nil { 370 switch t := s.Signer.(type) { 371 case *SignerPubKey: 372 return t.PubKey 373 } 374 } 375 return nil 376 } 377 378 func (s Signer) GetSignerETHAddress() *ETHAddress { 379 if s.Signer != nil { 380 switch t := s.Signer.(type) { 381 case *SignerETHAddress: 382 return t.ETHAddress 383 } 384 } 385 return nil 386 } 387 388 func (s Signer) GetSignerType() SignerType { 389 if s.Signer != nil { 390 switch s.Signer.(type) { 391 case *SignerPubKey: 392 return SignerTypePubKey 393 case *SignerETHAddress: 394 return SignerTypeEthAddress 395 } 396 } 397 398 return SignerTypeUnspecified 399 } 400 401 func SignerFromProto(s *datapb.Signer) *Signer { 402 signer := &Signer{} 403 404 if s.Signer != nil { 405 switch t := s.Signer.(type) { 406 case *datapb.Signer_PubKey: 407 signer.Signer = PubKeyFromProto(t) 408 case *datapb.Signer_EthAddress: 409 signer.Signer = ETHAddressFromProto(t) 410 } 411 } 412 413 return signer 414 } 415 416 func CreateSignerFromString(s string, t SignerType) *Signer { 417 signer := &Signer{} 418 switch t { 419 case SignerTypePubKey: 420 signer.Signer = &SignerPubKey{PubKey: &PubKey{s}} 421 case SignerTypeEthAddress: 422 signer.Signer = &SignerETHAddress{ETHAddress: ÐAddress{s}} 423 } 424 425 return signer 426 } 427 428 // SignersIntoProto returns a list of signers after checking the list length. 429 func SignersIntoProto(s []*Signer) []*datapb.Signer { 430 protoSigners := []*datapb.Signer{} 431 if len(s) > 0 { 432 protoSigners = make([]*datapb.Signer, len(s)) 433 for i, signer := range s { 434 if signer != nil { 435 sign := signer.oneOfProto() 436 protoSigners[i] = sign.(*datapb.Signer) 437 } 438 } 439 } 440 441 return protoSigners 442 } 443 444 func SignersToStringList(s []*Signer) []string { 445 var signers []string 446 447 if len(s) > 0 { 448 for _, signer := range s { 449 if signer != nil { 450 signers = append(signers, signer.String()) 451 } 452 } 453 return signers 454 } 455 return signers 456 } 457 458 // SignersFromProto returns a list of signers. 459 // The list is allowed to be empty. 460 func SignersFromProto(s []*datapb.Signer) []*Signer { 461 signers := []*Signer{} 462 if len(s) > 0 { 463 signers = make([]*Signer, len(s)) 464 for i, signer := range s { 465 if s != nil { 466 signers[i] = SignerFromProto(signer) 467 } 468 } 469 return signers 470 } 471 return signers 472 } 473 474 // Encoding and decoding options 475 476 const ( 477 SignerPubKeyPrepend = 0x00 478 ETHAddressPrepend = 0x01 479 ) 480 481 // SignerAsHex represents the signer as a hex encoded string. 482 // We export this function as a standalone option because there are cases when we are not sure 483 // what is the signer type we deal with. 484 func SignerAsHex(signer *Signer) (*Signer, error) { 485 switch signer.GetSignerType() { 486 case SignerTypePubKey: 487 if signer.Signer != nil { 488 s, err := signer.Signer.(*SignerPubKey).AsHex(false) 489 return &Signer{s}, err 490 } 491 return nil, errors.ErrSignerIsEmpty 492 493 case SignerTypeEthAddress: 494 if signer.Signer != nil { 495 s, err := signer.Signer.(*SignerETHAddress).AsHex(false) 496 return &Signer{s}, err 497 } 498 return nil, errors.ErrSignerIsEmpty 499 } 500 501 // If the signer type is not among the ones we know, we do not care to 502 // encode or decode it. 503 return nil, errors.ErrSignerUnknownType 504 } 505 506 // SignerAsString represents the Signer content as a string. 507 func SignerAsString(signer *Signer) (*Signer, error) { 508 switch signer.GetSignerType() { 509 case SignerTypePubKey: 510 if signer.Signer != nil { 511 s, err := signer.Signer.(*SignerPubKey).AsString() 512 513 return &Signer{s}, err 514 } 515 return nil, errors.ErrSignerIsEmpty 516 517 case SignerTypeEthAddress: 518 if signer.Signer != nil { 519 s, err := signer.Signer.(*SignerETHAddress).AsString() 520 return &Signer{s}, err 521 } 522 return nil, errors.ErrSignerIsEmpty 523 } 524 525 // If the signer type is not among the ones we know, we do not care to 526 // encode or decode it. 527 return nil, errors.ErrSignerUnknownType 528 } 529 530 func isHex(src string) (bool, error) { 531 dst := make([]byte, hex.DecodedLen(len(src))) 532 if _, err := hex.Decode(dst, []byte(src)); err != nil { 533 return false, fmt.Errorf("string is not a valid hex: %v", err) 534 } 535 536 return true, nil 537 } 538 539 // Serialization and deserialization 540 541 // SerializeSigner deserializes the signer to a byte slice - we use that 542 // type top insert it into the database. 543 // The deserialization prepends the slice with two bytes as signer type indicator - 544 // that is used when the Signer is serialized back. 545 func (s *Signer) Serialize() ([]byte, error) { 546 switch s.GetSignerType() { 547 case SignerTypePubKey: 548 if s.Signer != nil { 549 pk, _ := s.Signer.(*SignerPubKey) 550 if pk.PubKey != nil { 551 return pk.Serialize(), nil 552 } 553 } 554 return nil, errors.ErrSignerIsEmpty 555 556 case SignerTypeEthAddress: 557 if s.Signer != nil { 558 ea, _ := s.Signer.(*SignerETHAddress) 559 if ea.ETHAddress != nil { 560 return ea.Serialize(), nil 561 } 562 } 563 return nil, errors.ErrSignerIsEmpty 564 } 565 566 // If the signer type is not among the ones we know, we do not care to 567 // encode or decode it. 568 return nil, errors.ErrSignerUnknownType 569 } 570 571 func DeserializeSigner(content []byte) *Signer { 572 if len(content) > 0 { 573 switch content[0] { 574 case SignerPubKeyPrepend: 575 return &Signer{ 576 Signer: DeserializePubKey(content[1:]), 577 } 578 579 case ETHAddressPrepend: 580 return &Signer{ 581 Signer: DeserializeETHAddress(content[1:]), 582 } 583 } 584 } 585 // If the signer type is not among the ones we know, we do not care to 586 // encode or decode it. 587 return &Signer{Signer: nil} 588 } 589 590 func NewSigner(t SignerType) *Signer { 591 switch t { 592 case SignerTypePubKey: 593 return &Signer{ 594 Signer: &SignerPubKey{}, 595 } 596 597 case SignerTypeEthAddress: 598 return &Signer{ 599 Signer: &SignerETHAddress{}, 600 } 601 } 602 // No indication if the given type is unknown. 603 return nil 604 } 605 606 type SpecSigners []*Signer 607 608 func (s SpecSigners) String() string { 609 allSigners := []string{} 610 for _, signer := range s { 611 allSigners = append(allSigners, signer.String()) 612 } 613 return "[" + strings.Join(allSigners, ", ") + "]" 614 }