@@ -22,12 +22,49 @@ import (
2222 "math/big"
2323 "os"
2424 "reflect"
25+ "sync"
2526 "time"
2627
2728 "github.com/blinklabs-io/gouroboros/cbor"
2829 "github.com/blinklabs-io/gouroboros/ledger/common"
2930)
3031
32+ // Network stake address headers
33+ var (
34+ stakeHeaderRegistry = map [string ]struct {
35+ Base , Script byte
36+ }{
37+ "Mainnet" : {0xE0 , 0xE1 },
38+ "Testnet" : {0xF0 , 0xF1 },
39+ }
40+ stakeHeaderMutex sync.RWMutex
41+ )
42+
43+ // RegisterStakeHeaders allows runtime registration of network address headers
44+ func RegisterStakeHeaders (networkId string , baseHeader , scriptHeader byte ) {
45+ stakeHeaderMutex .Lock ()
46+ defer stakeHeaderMutex .Unlock ()
47+ stakeHeaderRegistry [networkId ] = struct { Base , Script byte }{
48+ Base : baseHeader ,
49+ Script : scriptHeader ,
50+ }
51+ }
52+
53+ func getStakeAddressHeader (networkId string , isScript bool ) (byte , error ) {
54+ stakeHeaderMutex .RLock ()
55+ defer stakeHeaderMutex .RUnlock ()
56+
57+ headers , exists := stakeHeaderRegistry [networkId ]
58+ if ! exists {
59+ return 0 , errors .New ("network not registered in stake header registry" )
60+ }
61+
62+ if isScript {
63+ return headers .Script , nil
64+ }
65+ return headers .Base , nil
66+ }
67+
3168type ShelleyGenesis struct {
3269 cbor.StructAsArray
3370 SystemStart time.Time `json:"systemStart"`
@@ -232,7 +269,6 @@ func (g *ShelleyGenesis) GenesisUtxos() ([]common.Utxo, error) {
232269 return ret , nil
233270}
234271
235- // InitialPools returns all pools and their delegators from the genesis data
236272func (g * ShelleyGenesis ) InitialPools () (map [string ]common.PoolRegistrationCertificate , map [string ][]common.Address , error ) {
237273 pools := make (map [string ]common.PoolRegistrationCertificate )
238274 poolStake := make (map [string ][]common.Address )
@@ -241,6 +277,11 @@ func (g *ShelleyGenesis) InitialPools() (map[string]common.PoolRegistrationCerti
241277 return pools , poolStake , nil
242278 }
243279
280+ headerByte , err := getStakeAddressHeader (g .NetworkId , true )
281+ if err != nil {
282+ return nil , nil , errors .New ("failed to get stake address header" )
283+ }
284+
244285 for stakeAddr , poolId := range g .Staking .Stake {
245286 if len (stakeAddr ) != 56 {
246287 return nil , nil , errors .New ("invalid stake address length" )
@@ -251,7 +292,7 @@ func (g *ShelleyGenesis) InitialPools() (map[string]common.PoolRegistrationCerti
251292 return nil , nil , errors .New ("failed to decode stake key" )
252293 }
253294
254- stakeAddrBytes := append ([]byte {0xE1 }, stakeKeyBytes ... )
295+ stakeAddrBytes := append ([]byte {headerByte }, stakeKeyBytes ... )
255296 addr , err := common .NewAddressFromBytes (stakeAddrBytes )
256297 if err != nil {
257298 return nil , nil , errors .New ("failed to create stake address" )
@@ -286,7 +327,6 @@ func (g *ShelleyGenesis) InitialPools() (map[string]common.PoolRegistrationCerti
286327 return pools , poolStake , nil
287328}
288329
289- // PoolById returns a specific pool by its ID along with its delegators
290330func (g * ShelleyGenesis ) PoolById (poolId string ) (* common.PoolRegistrationCertificate , []common.Address , error ) {
291331 if len (poolId ) != 56 {
292332 return nil , nil , errors .New ("invalid pool ID length" )
@@ -297,9 +337,9 @@ func (g *ShelleyGenesis) PoolById(poolId string) (*common.PoolRegistrationCertif
297337 return nil , nil , errors .New ("pool not found" )
298338 }
299339
300- operatorBytes , err := hex . DecodeString ( poolId )
340+ headerByte , err := getStakeAddressHeader ( g . NetworkId , true )
301341 if err != nil {
302- return nil , nil , errors .New ("failed to decode pool operator key " )
342+ return nil , nil , errors .New ("failed to get stake address header " )
303343 }
304344
305345 var delegators []common.Address
@@ -314,7 +354,7 @@ func (g *ShelleyGenesis) PoolById(poolId string) (*common.PoolRegistrationCertif
314354 return nil , nil , errors .New ("failed to decode stake key" )
315355 }
316356
317- stakeAddrBytes := append ([]byte {0xE1 }, stakeKeyBytes ... )
357+ stakeAddrBytes := append ([]byte {headerByte }, stakeKeyBytes ... )
318358 addr , err := common .NewAddressFromBytes (stakeAddrBytes )
319359 if err != nil {
320360 return nil , nil , errors .New ("failed to create stake address" )
@@ -324,6 +364,11 @@ func (g *ShelleyGenesis) PoolById(poolId string) (*common.PoolRegistrationCertif
324364 }
325365 }
326366
367+ operatorBytes , err := hex .DecodeString (poolId )
368+ if err != nil {
369+ return nil , nil , errors .New ("failed to decode pool operator key" )
370+ }
371+
327372 return & common.PoolRegistrationCertificate {
328373 Operator : common .Blake2b224 (operatorBytes ),
329374 VrfKeyHash : pool .VrfKeyHash ,
0 commit comments