@@ -58,7 +58,6 @@ const (
58
58
var (
59
59
_ State = (* state )(nil )
60
60
61
- ErrCantFindSubnet = errors .New ("couldn't find subnet" )
62
61
errMissingValidatorSet = errors .New ("missing validator set" )
63
62
errValidatorSetAlreadyPopulated = errors .New ("validator set already populated" )
64
63
errDuplicateValidatorSet = errors .New ("duplicate validator set" )
81
80
rewardUTXOsPrefix = []byte ("rewardUTXOs" )
82
81
utxoPrefix = []byte ("utxo" )
83
82
subnetPrefix = []byte ("subnet" )
83
+ subnetOwnerPrefix = []byte ("subnetOwner" )
84
84
transformedSubnetPrefix = []byte ("transformedSubnet" )
85
85
supplyPrefix = []byte ("supply" )
86
86
chainPrefix = []byte ("chain" )
@@ -115,6 +115,7 @@ type Chain interface {
115
115
AddSubnet (createSubnetTx * txs.Tx )
116
116
117
117
GetSubnetOwner (subnetID ids.ID ) (fx.Owner , error )
118
+ SetSubnetOwner (subnetID ids.ID , owner fx.Owner )
118
119
119
120
GetSubnetTransformation (subnetID ids.ID ) (* txs.Tx , error )
120
121
AddSubnetTransformation (transformSubnetTx * txs.Tx )
@@ -274,6 +275,8 @@ type stateBlk struct {
274
275
* |-. subnets
275
276
* | '-. list
276
277
* | '-- txID -> nil
278
+ * |-. subnetOwners
279
+ * | '-. subnetID -> owner
277
280
* |-. chains
278
281
* | '-. subnetID
279
282
* | '-. list
@@ -352,6 +355,11 @@ type state struct {
352
355
subnetBaseDB database.Database
353
356
subnetDB linkeddb.LinkedDB
354
357
358
+ // Subnet ID --> Owner of the subnet
359
+ subnetOwners map [ids.ID ]fx.Owner
360
+ subnetOwnerCache cache.Cacher [ids.ID , fxOwnerAndSize ] // cache of subnetID -> owner if the entry is nil, it is not in the database
361
+ subnetOwnerDB database.Database
362
+
355
363
transformedSubnets map [ids.ID ]* txs.Tx // map of subnetID -> transformSubnetTx
356
364
transformedSubnetCache cache.Cacher [ids.ID , * txs.Tx ] // cache of subnetID -> transformSubnetTx if the entry is nil, it is not in the database
357
365
transformedSubnetDB database.Database
@@ -420,6 +428,11 @@ type txAndStatus struct {
420
428
status status.Status
421
429
}
422
430
431
+ type fxOwnerAndSize struct {
432
+ owner fx.Owner
433
+ size int
434
+ }
435
+
423
436
func txSize (_ ids.ID , tx * txs.Tx ) int {
424
437
if tx == nil {
425
438
return ids .IDLen + constants .PointerOverhead
@@ -573,6 +586,18 @@ func newState(
573
586
574
587
subnetBaseDB := prefixdb .New (subnetPrefix , baseDB )
575
588
589
+ subnetOwnerDB := prefixdb .New (subnetOwnerPrefix , baseDB )
590
+ subnetOwnerCache , err := metercacher .New [ids.ID , fxOwnerAndSize ](
591
+ "subnet_owner_cache" ,
592
+ metricsReg ,
593
+ cache .NewSizedLRU [ids.ID , fxOwnerAndSize ](execCfg .FxOwnerCacheSize , func (_ ids.ID , f fxOwnerAndSize ) int {
594
+ return ids .IDLen + f .size
595
+ }),
596
+ )
597
+ if err != nil {
598
+ return nil , err
599
+ }
600
+
576
601
transformedSubnetCache , err := metercacher .New (
577
602
"transformed_subnet_cache" ,
578
603
metricsReg ,
@@ -669,6 +694,10 @@ func newState(
669
694
subnetBaseDB : subnetBaseDB ,
670
695
subnetDB : linkeddb .NewDefault (subnetBaseDB ),
671
696
697
+ subnetOwners : make (map [ids.ID ]fx.Owner ),
698
+ subnetOwnerDB : subnetOwnerDB ,
699
+ subnetOwnerCache : subnetOwnerCache ,
700
+
672
701
transformedSubnets : make (map [ids.ID ]* txs.Tx ),
673
702
transformedSubnetCache : transformedSubnetCache ,
674
703
transformedSubnetDB : prefixdb .New (transformedSubnetPrefix , baseDB ),
@@ -819,24 +848,54 @@ func (s *state) AddSubnet(createSubnetTx *txs.Tx) {
819
848
}
820
849
821
850
func (s * state ) GetSubnetOwner (subnetID ids.ID ) (fx.Owner , error ) {
851
+ if owner , exists := s .subnetOwners [subnetID ]; exists {
852
+ return owner , nil
853
+ }
854
+
855
+ if ownerAndSize , cached := s .subnetOwnerCache .Get (subnetID ); cached {
856
+ if ownerAndSize .owner == nil {
857
+ return nil , database .ErrNotFound
858
+ }
859
+ return ownerAndSize .owner , nil
860
+ }
861
+
862
+ ownerBytes , err := s .subnetOwnerDB .Get (subnetID [:])
863
+ if err == nil {
864
+ var owner fx.Owner
865
+ if _ , err := block .GenesisCodec .Unmarshal (ownerBytes , & owner ); err != nil {
866
+ return nil , err
867
+ }
868
+ s .subnetOwnerCache .Put (subnetID , fxOwnerAndSize {
869
+ owner : owner ,
870
+ size : len (ownerBytes ),
871
+ })
872
+ return owner , nil
873
+ }
874
+ if err != database .ErrNotFound {
875
+ return nil , err
876
+ }
877
+
822
878
subnetIntf , _ , err := s .GetTx (subnetID )
823
879
if err != nil {
824
- return nil , fmt .Errorf (
825
- "%w %q: %w" ,
826
- ErrCantFindSubnet ,
827
- subnetID ,
828
- err ,
829
- )
880
+ if err == database .ErrNotFound {
881
+ s .subnetOwnerCache .Put (subnetID , fxOwnerAndSize {})
882
+ }
883
+ return nil , err
830
884
}
831
885
832
886
subnet , ok := subnetIntf .Unsigned .(* txs.CreateSubnetTx )
833
887
if ! ok {
834
888
return nil , fmt .Errorf ("%q %w" , subnetID , errIsNotSubnet )
835
889
}
836
890
891
+ s .SetSubnetOwner (subnetID , subnet .Owner )
837
892
return subnet .Owner , nil
838
893
}
839
894
895
+ func (s * state ) SetSubnetOwner (subnetID ids.ID , owner fx.Owner ) {
896
+ s .subnetOwners [subnetID ] = owner
897
+ }
898
+
840
899
func (s * state ) GetSubnetTransformation (subnetID ids.ID ) (* txs.Tx , error ) {
841
900
if tx , exists := s .transformedSubnets [subnetID ]; exists {
842
901
return tx , nil
@@ -1683,6 +1742,7 @@ func (s *state) write(updateValidators bool, height uint64) error {
1683
1742
s .writeRewardUTXOs (),
1684
1743
s .writeUTXOs (),
1685
1744
s .writeSubnets (),
1745
+ s .writeSubnetOwners (),
1686
1746
s .writeTransformedSubnets (),
1687
1747
s .writeSubnetSupplies (),
1688
1748
s .writeChains (),
@@ -2273,6 +2333,29 @@ func (s *state) writeSubnets() error {
2273
2333
return nil
2274
2334
}
2275
2335
2336
+ func (s * state ) writeSubnetOwners () error {
2337
+ for subnetID , owner := range s .subnetOwners {
2338
+ subnetID := subnetID
2339
+ owner := owner
2340
+ delete (s .subnetOwners , subnetID )
2341
+
2342
+ ownerBytes , err := block .GenesisCodec .Marshal (block .Version , & owner )
2343
+ if err != nil {
2344
+ return fmt .Errorf ("failed to marshal subnet owner: %w" , err )
2345
+ }
2346
+
2347
+ s .subnetOwnerCache .Put (subnetID , fxOwnerAndSize {
2348
+ owner : owner ,
2349
+ size : len (ownerBytes ),
2350
+ })
2351
+
2352
+ if err := s .subnetOwnerDB .Put (subnetID [:], ownerBytes ); err != nil {
2353
+ return fmt .Errorf ("failed to write subnet owner: %w" , err )
2354
+ }
2355
+ }
2356
+ return nil
2357
+ }
2358
+
2276
2359
func (s * state ) writeTransformedSubnets () error {
2277
2360
for subnetID , tx := range s .transformedSubnets {
2278
2361
txID := tx .ID ()
0 commit comments