|
15 | 15 | package common
|
16 | 16 |
|
17 | 17 | import (
|
| 18 | + "encoding/hex" |
| 19 | + "encoding/json" |
18 | 20 | "errors"
|
19 | 21 | "fmt"
|
20 | 22 | "net"
|
@@ -299,11 +301,11 @@ const (
|
299 | 301 | )
|
300 | 302 |
|
301 | 303 | type PoolRelay struct {
|
302 |
| - Type int |
303 |
| - Port *uint32 |
304 |
| - Ipv4 *net.IP |
305 |
| - Ipv6 *net.IP |
306 |
| - Hostname *string |
| 304 | + Type int `json:"type"` |
| 305 | + Port *uint32 `json:"port,omitempty"` |
| 306 | + Ipv4 *net.IP `json:"ipv4,omitempty"` |
| 307 | + Ipv6 *net.IP `json:"ipv6,omitempty"` |
| 308 | + Hostname *string `json:"hostname,omitempty"` |
307 | 309 | }
|
308 | 310 |
|
309 | 311 | func (p *PoolRelay) UnmarshalCBOR(data []byte) error {
|
@@ -373,18 +375,121 @@ func (p *PoolRelay) Utxorpc() (*utxorpc.Relay, error) {
|
373 | 375 | }
|
374 | 376 |
|
375 | 377 | type PoolRegistrationCertificate struct {
|
376 |
| - cbor.StructAsArray |
377 |
| - cbor.DecodeStoreCbor |
378 |
| - CertType uint |
379 |
| - Operator PoolKeyHash |
380 |
| - VrfKeyHash VrfKeyHash |
381 |
| - Pledge uint64 |
382 |
| - Cost uint64 |
383 |
| - Margin cbor.Rat |
384 |
| - RewardAccount AddrKeyHash |
385 |
| - PoolOwners []AddrKeyHash |
386 |
| - Relays []PoolRelay |
387 |
| - PoolMetadata *PoolMetadata |
| 378 | + cbor.StructAsArray `json:"-"` |
| 379 | + cbor.DecodeStoreCbor `json:"-"` |
| 380 | + CertType uint `json:"certType,omitempty"` |
| 381 | + Operator PoolKeyHash `json:"operator"` |
| 382 | + VrfKeyHash VrfKeyHash `json:"vrfKeyHash"` |
| 383 | + Pledge uint64 `json:"pledge"` |
| 384 | + Cost uint64 `json:"cost"` |
| 385 | + Margin GenesisRat `json:"margin"` |
| 386 | + RewardAccount AddrKeyHash `json:"rewardAccount"` |
| 387 | + PoolOwners []AddrKeyHash `json:"poolOwners"` |
| 388 | + Relays []PoolRelay `json:"relays"` |
| 389 | + PoolMetadata *PoolMetadata `json:"poolMetadata,omitempty"` |
| 390 | +} |
| 391 | + |
| 392 | +func (p *PoolRegistrationCertificate) UnmarshalJSON(data []byte) error { |
| 393 | + type tempPool struct { |
| 394 | + Operator string `json:"operator"` |
| 395 | + VrfKeyHash string `json:"vrfKeyHash"` |
| 396 | + Pledge uint64 `json:"pledge"` |
| 397 | + Cost uint64 `json:"cost"` |
| 398 | + Margin json.RawMessage `json:"margin"` |
| 399 | + RewardAccount json.RawMessage `json:"rewardAccount"` |
| 400 | + PoolOwners []string `json:"poolOwners"` |
| 401 | + Relays []struct { |
| 402 | + Type int `json:"type"` |
| 403 | + Port *uint32 `json:"port,omitempty"` |
| 404 | + Ipv4 *net.IP `json:"ipv4,omitempty"` |
| 405 | + Ipv6 *net.IP `json:"ipv6,omitempty"` |
| 406 | + Hostname *string `json:"hostname,omitempty"` |
| 407 | + } `json:"relays"` |
| 408 | + PoolMetadata *PoolMetadata `json:"poolMetadata,omitempty"` |
| 409 | + } |
| 410 | + |
| 411 | + var tmp tempPool |
| 412 | + //nolint:musttag |
| 413 | + if err := json.Unmarshal(data, &tmp); err != nil { |
| 414 | + return fmt.Errorf("failed to unmarshal pool registration: %w", err) |
| 415 | + } |
| 416 | + |
| 417 | + p.Pledge = tmp.Pledge |
| 418 | + p.Cost = tmp.Cost |
| 419 | + p.Relays = make([]PoolRelay, len(tmp.Relays)) |
| 420 | + for i, relay := range tmp.Relays { |
| 421 | + p.Relays[i] = PoolRelay{ |
| 422 | + Type: relay.Type, |
| 423 | + Port: relay.Port, |
| 424 | + Ipv4: relay.Ipv4, |
| 425 | + Ipv6: relay.Ipv6, |
| 426 | + Hostname: relay.Hostname, |
| 427 | + } |
| 428 | + } |
| 429 | + p.PoolMetadata = tmp.PoolMetadata |
| 430 | + |
| 431 | + // Handle margin field |
| 432 | + if len(tmp.Margin) > 0 { |
| 433 | + if err := p.Margin.UnmarshalJSON(tmp.Margin); err != nil { |
| 434 | + return fmt.Errorf("failed to unmarshal margin: %w", err) |
| 435 | + } |
| 436 | + } |
| 437 | + |
| 438 | + // Handle reward account |
| 439 | + if len(tmp.RewardAccount) > 0 { |
| 440 | + var ra struct { |
| 441 | + Credential struct { |
| 442 | + KeyHash string `json:"key hash"` |
| 443 | + } `json:"credential"` |
| 444 | + } |
| 445 | + if err := json.Unmarshal(tmp.RewardAccount, &ra); err != nil { |
| 446 | + return fmt.Errorf("failed to unmarshal reward account: %w", err) |
| 447 | + } |
| 448 | + |
| 449 | + if ra.Credential.KeyHash != "" { |
| 450 | + hashBytes, err := hex.DecodeString(ra.Credential.KeyHash) |
| 451 | + if err != nil { |
| 452 | + return fmt.Errorf("failed to decode reward account key hash: %w", err) |
| 453 | + } |
| 454 | + if len(hashBytes) != AddressHashSize { |
| 455 | + return fmt.Errorf("invalid key hash length: expected %d, got %d", AddressHashSize, len(hashBytes)) |
| 456 | + } |
| 457 | + p.RewardAccount = AddrKeyHash(NewBlake2b224(hashBytes)) |
| 458 | + } |
| 459 | + } |
| 460 | + |
| 461 | + // Convert operator key |
| 462 | + if tmp.Operator != "" { |
| 463 | + opBytes, err := hex.DecodeString(tmp.Operator) |
| 464 | + if err != nil { |
| 465 | + return fmt.Errorf("invalid operator key: %w", err) |
| 466 | + } |
| 467 | + p.Operator = PoolKeyHash(NewBlake2b224(opBytes)) |
| 468 | + } |
| 469 | + |
| 470 | + // Convert VRF key hash |
| 471 | + if tmp.VrfKeyHash != "" { |
| 472 | + vrfBytes, err := hex.DecodeString(tmp.VrfKeyHash) |
| 473 | + if err != nil { |
| 474 | + return fmt.Errorf("invalid VRF key hash: %w", err) |
| 475 | + } |
| 476 | + p.VrfKeyHash = VrfKeyHash(NewBlake2b256(vrfBytes)) |
| 477 | + } |
| 478 | + |
| 479 | + // Convert pool owners |
| 480 | + if len(tmp.PoolOwners) > 0 { |
| 481 | + owners := make([]AddrKeyHash, len(tmp.PoolOwners)) |
| 482 | + for i, owner := range tmp.PoolOwners { |
| 483 | + ownerBytes, err := hex.DecodeString(owner) |
| 484 | + if err != nil { |
| 485 | + return fmt.Errorf("invalid pool owner key: %w", err) |
| 486 | + } |
| 487 | + owners[i] = AddrKeyHash(NewBlake2b224(ownerBytes)) |
| 488 | + } |
| 489 | + p.PoolOwners = owners |
| 490 | + } |
| 491 | + |
| 492 | + return nil |
388 | 493 | }
|
389 | 494 |
|
390 | 495 | func (c PoolRegistrationCertificate) isCertificate() {}
|
|
0 commit comments