Skip to content

Commit c90352f

Browse files
authored
feat(shelley): created genesis pools from shelley genesis (#1054)
Signed-off-by: Jenita <[email protected]>
1 parent a33de47 commit c90352f

File tree

4 files changed

+527
-34
lines changed

4 files changed

+527
-34
lines changed

ledger/common/address.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,23 +108,40 @@ func NewAddressFromParts(
108108
paymentAddr []byte,
109109
stakingAddr []byte,
110110
) (Address, error) {
111+
// Validate network ID
112+
if networkId != AddressNetworkTestnet && networkId != AddressNetworkMainnet {
113+
return Address{}, errors.New("invalid network ID")
114+
}
115+
116+
// Handle stake-only addresses
117+
if addrType == AddressTypeNoneKey || addrType == AddressTypeNoneScript {
118+
if len(paymentAddr) > 0 {
119+
return Address{}, errors.New("payment address must be empty for stake-only addresses")
120+
}
121+
if len(stakingAddr) != AddressHashSize {
122+
return Address{}, fmt.Errorf("staking key must be exactly %d bytes", AddressHashSize)
123+
}
124+
return Address{
125+
addressType: addrType,
126+
networkId: networkId,
127+
stakingAddress: stakingAddr,
128+
}, nil
129+
}
130+
131+
// Handle regular addresses
111132
if len(paymentAddr) != AddressHashSize {
112-
return Address{}, fmt.Errorf(
113-
"invalid payment address hash length: %d",
114-
len(paymentAddr),
115-
)
133+
return Address{}, fmt.Errorf("payment address must be exactly %d bytes", AddressHashSize)
116134
}
135+
117136
if len(stakingAddr) > 0 && len(stakingAddr) != AddressHashSize {
118-
return Address{}, fmt.Errorf(
119-
"invalid staking address hash length: %d",
120-
len(stakingAddr),
121-
)
137+
return Address{}, fmt.Errorf("staking address must be empty or exactly %d bytes", AddressHashSize)
122138
}
139+
123140
return Address{
124141
addressType: addrType,
125142
networkId: networkId,
126-
paymentAddress: paymentAddr[:],
127-
stakingAddress: stakingAddr[:],
143+
paymentAddress: paymentAddr,
144+
stakingAddress: stakingAddr,
128145
}, nil
129146
}
130147

ledger/common/certs.go

Lines changed: 122 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package common
1616

1717
import (
18+
"encoding/hex"
19+
"encoding/json"
1820
"errors"
1921
"fmt"
2022
"net"
@@ -299,11 +301,11 @@ const (
299301
)
300302

301303
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"`
307309
}
308310

309311
func (p *PoolRelay) UnmarshalCBOR(data []byte) error {
@@ -373,18 +375,121 @@ func (p *PoolRelay) Utxorpc() (*utxorpc.Relay, error) {
373375
}
374376

375377
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
388493
}
389494

390495
func (c PoolRegistrationCertificate) isCertificate() {}

0 commit comments

Comments
 (0)