@@ -3,37 +3,57 @@ package types
33import (
44 "context"
55 "fmt"
6+ "os"
67 "sync"
78
89 "github.com/cosmos/cosmos-sdk/version"
910)
1011
11- // DefaultKeyringServiceName defines a default service name for the keyring.
12- const DefaultKeyringServiceName = "cosmos"
12+ const (
13+ DefaultKeyringServiceName = "cosmos"
14+ EnvConfigScope = "COSMOS_SDK_CONFIG_SCOPE"
15+ )
1316
14- // Config is the structure that holds the SDK configuration parameters.
15- // This could be used to initialize certain configuration parameters for the SDK.
1617type Config struct {
1718 fullFundraiserPath string
1819 bech32AddressPrefix map [string ]string
1920 txEncoder TxEncoder
2021 addressVerifier func ([]byte ) error
2122 mtx sync.RWMutex
2223
23- // SLIP-44 related
2424 purpose uint32
2525 coinType uint32
2626
2727 sealed bool
2828 sealedch chan struct {}
2929}
3030
31- // cosmos-sdk wide global singleton
3231var (
33- sdkConfig * Config
34- initConfig sync.Once
32+ configRegistry = make ( map [ string ] * Config )
33+ registryMutex sync.Mutex
3534)
3635
36+ // getConfigKey returns a unique config scope identifier.
37+ // It uses ENV override, or defaults to "hostname|binary|pid".
38+ func getConfigKey () string {
39+ if id := os .Getenv (EnvConfigScope ); id != "" {
40+ return id
41+ }
42+
43+ exe , errExec := os .Executable ()
44+ host , errHost := os .Hostname ()
45+ pid := os .Getpid ()
46+
47+ if errExec != nil {
48+ exe = "unknown-exe"
49+ }
50+ if errHost != nil {
51+ host = "unknown-host"
52+ }
53+
54+ return fmt .Sprintf ("%s|%s|%d" , host , exe , pid )
55+ }
56+
3757// NewConfig returns a new Config with default values.
3858func NewConfig () * Config {
3959 return & Config {
@@ -47,74 +67,59 @@ func NewConfig() *Config {
4767 "consensus_pub" : Bech32PrefixConsPub ,
4868 },
4969 fullFundraiserPath : FullFundraiserPath ,
50-
51- purpose : Purpose ,
52- coinType : CoinType ,
53- txEncoder : nil ,
70+ purpose : Purpose ,
71+ coinType : CoinType ,
5472 }
5573}
5674
57- // GetConfig returns the config instance for the SDK .
75+ // GetConfig returns a per-scope config instance.
5876func GetConfig () * Config {
59- initConfig .Do (func () {
60- sdkConfig = NewConfig ()
61- })
62- return sdkConfig
63- }
77+ key := getConfigKey ()
6478
65- // GetSealedConfig returns the config instance for the SDK if/once it is sealed.
66- func GetSealedConfig (ctx context.Context ) (* Config , error ) {
67- config := GetConfig ()
68- select {
69- case <- config .sealedch :
70- return config , nil
71- case <- ctx .Done ():
72- return nil , ctx .Err ()
79+ registryMutex .Lock ()
80+ defer registryMutex .Unlock ()
81+
82+ if cfg , exists := configRegistry [key ]; exists {
83+ return cfg
7384 }
85+
86+ cfg := NewConfig ()
87+ configRegistry [key ] = cfg
88+
89+ return cfg
7490}
7591
7692func (config * Config ) assertNotSealed () {
7793 config .mtx .RLock ()
7894 defer config .mtx .RUnlock ()
79-
8095 if config .sealed {
8196 panic ("Config is sealed" )
8297 }
8398}
8499
85- // SetBech32PrefixForAccount builds the Config with Bech32 addressPrefix and publKeyPrefix for accounts
86- // and returns the config instance
87100func (config * Config ) SetBech32PrefixForAccount (addressPrefix , pubKeyPrefix string ) {
88101 config .assertNotSealed ()
89102 config .bech32AddressPrefix ["account_addr" ] = addressPrefix
90103 config .bech32AddressPrefix ["account_pub" ] = pubKeyPrefix
91104}
92105
93- // SetBech32PrefixForValidator builds the Config with Bech32 addressPrefix and publKeyPrefix for validators
94- //
95- // and returns the config instance
96106func (config * Config ) SetBech32PrefixForValidator (addressPrefix , pubKeyPrefix string ) {
97107 config .assertNotSealed ()
98108 config .bech32AddressPrefix ["validator_addr" ] = addressPrefix
99109 config .bech32AddressPrefix ["validator_pub" ] = pubKeyPrefix
100110}
101111
102- // SetBech32PrefixForConsensusNode builds the Config with Bech32 addressPrefix and publKeyPrefix for consensus nodes
103- // and returns the config instance
104112func (config * Config ) SetBech32PrefixForConsensusNode (addressPrefix , pubKeyPrefix string ) {
105113 config .assertNotSealed ()
106114 config .bech32AddressPrefix ["consensus_addr" ] = addressPrefix
107115 config .bech32AddressPrefix ["consensus_pub" ] = pubKeyPrefix
108116}
109117
110- // SetTxEncoder builds the Config with TxEncoder used to marshal StdTx to bytes
111118func (config * Config ) SetTxEncoder (encoder TxEncoder ) {
112119 config .assertNotSealed ()
113120 config .txEncoder = encoder
114121}
115122
116- // SetAddressVerifier builds the Config with the provided function for verifying that addresses
117- // have the correct format
118123func (config * Config ) SetAddressVerifier (addressVerifier func ([]byte ) error ) {
119124 config .assertNotSealed ()
120125 config .addressVerifier = addressVerifier
@@ -140,81 +145,64 @@ func (config *Config) SetCoinType(coinType uint32) {
140145 config .coinType = coinType
141146}
142147
143- // Seal seals the config such that the config state could not be modified further
144148func (config * Config ) Seal () * Config {
145149 config .mtx .Lock ()
150+ defer config .mtx .Unlock ()
146151
147152 if config .sealed {
148- config .mtx .Unlock ()
149153 return config
150154 }
151155
152- // signal sealed after state exposed/unlocked
153156 config .sealed = true
154- config .mtx .Unlock ()
155157 close (config .sealedch )
156158
157159 return config
158160}
159161
160- // GetBech32AccountAddrPrefix returns the Bech32 prefix for account address
161162func (config * Config ) GetBech32AccountAddrPrefix () string {
162163 return config .bech32AddressPrefix ["account_addr" ]
163164}
164165
165- // GetBech32ValidatorAddrPrefix returns the Bech32 prefix for validator address
166166func (config * Config ) GetBech32ValidatorAddrPrefix () string {
167167 return config .bech32AddressPrefix ["validator_addr" ]
168168}
169169
170- // GetBech32ConsensusAddrPrefix returns the Bech32 prefix for consensus node address
171170func (config * Config ) GetBech32ConsensusAddrPrefix () string {
172171 return config .bech32AddressPrefix ["consensus_addr" ]
173172}
174173
175- // GetBech32AccountPubPrefix returns the Bech32 prefix for account public key
176174func (config * Config ) GetBech32AccountPubPrefix () string {
177175 return config .bech32AddressPrefix ["account_pub" ]
178176}
179177
180- // GetBech32ValidatorPubPrefix returns the Bech32 prefix for validator public key
181178func (config * Config ) GetBech32ValidatorPubPrefix () string {
182179 return config .bech32AddressPrefix ["validator_pub" ]
183180}
184181
185- // GetBech32ConsensusPubPrefix returns the Bech32 prefix for consensus node public key
186182func (config * Config ) GetBech32ConsensusPubPrefix () string {
187183 return config .bech32AddressPrefix ["consensus_pub" ]
188184}
189185
190- // GetTxEncoder return function to encode transactions
191186func (config * Config ) GetTxEncoder () TxEncoder {
192187 return config .txEncoder
193188}
194189
195- // GetAddressVerifier returns the function to verify that addresses have the correct format
196190func (config * Config ) GetAddressVerifier () func ([]byte ) error {
197191 return config .addressVerifier
198192}
199193
200- // GetPurpose returns the BIP-0044 Purpose code on the config.
201194func (config * Config ) GetPurpose () uint32 {
202195 return config .purpose
203196}
204197
205- // GetCoinType returns the BIP-0044 CoinType code on the config.
206198func (config * Config ) GetCoinType () uint32 {
207199 return config .coinType
208200}
209201
210- // GetFullFundraiserPath returns the BIP44Prefix.
211- //
212- // Deprecated: This method is supported for backward compatibility only and will be removed in a future release. Use GetFullBIP44Path instead.
213202func (config * Config ) GetFullFundraiserPath () string {
214203 return config .fullFundraiserPath
215204}
216205
217- // GetFullBIP44Path returns the BIP44Prefix.
218206func (config * Config ) GetFullBIP44Path () string {
219207 return fmt .Sprintf ("m/%d'/%d'/0'/0/0" , config .purpose , config .coinType )
220208}
@@ -225,3 +213,15 @@ func KeyringServiceName() string {
225213 }
226214 return version .Name
227215}
216+
217+ // Optional: expose sealed config with timeout
218+
219+ func GetSealedConfig (ctx context.Context ) (* Config , error ) {
220+ config := GetConfig ()
221+ select {
222+ case <- config .sealedch :
223+ return config , nil
224+ case <- ctx .Done ():
225+ return nil , ctx .Err ()
226+ }
227+ }
0 commit comments