-
Notifications
You must be signed in to change notification settings - Fork 807
add SetSubnetOwner
to Chain
interface
#2031
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e11c476
2d66725
e83458d
8f63ba4
a6364db
895f0c7
5faf60b
d65e483
9b5ad9e
32ce3b8
192e2f1
2a94bdf
7d59881
f43dc90
5e8c152
07b74c6
645013f
e0890d4
897ac65
c374609
54e6387
b3edbeb
60836b7
f1c86ca
bef73ab
28803b6
3a9bfaf
da17042
2154de3
4f0124a
4436795
85afb53
c6d03d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,7 +58,6 @@ const ( | |
var ( | ||
_ State = (*state)(nil) | ||
|
||
ErrCantFindSubnet = errors.New("couldn't find subnet") | ||
errMissingValidatorSet = errors.New("missing validator set") | ||
errValidatorSetAlreadyPopulated = errors.New("validator set already populated") | ||
errDuplicateValidatorSet = errors.New("duplicate validator set") | ||
|
@@ -81,6 +80,7 @@ var ( | |
rewardUTXOsPrefix = []byte("rewardUTXOs") | ||
utxoPrefix = []byte("utxo") | ||
subnetPrefix = []byte("subnet") | ||
subnetOwnerPrefix = []byte("subnetOwner") | ||
transformedSubnetPrefix = []byte("transformedSubnet") | ||
supplyPrefix = []byte("supply") | ||
chainPrefix = []byte("chain") | ||
|
@@ -115,6 +115,7 @@ type Chain interface { | |
AddSubnet(createSubnetTx *txs.Tx) | ||
|
||
GetSubnetOwner(subnetID ids.ID) (fx.Owner, error) | ||
SetSubnetOwner(subnetID ids.ID, owner fx.Owner) | ||
|
||
GetSubnetTransformation(subnetID ids.ID) (*txs.Tx, error) | ||
AddSubnetTransformation(transformSubnetTx *txs.Tx) | ||
|
@@ -274,6 +275,8 @@ type stateBlk struct { | |
* |-. subnets | ||
* | '-. list | ||
* | '-- txID -> nil | ||
* |-. subnetOwners | ||
* | '-. subnetID -> owner | ||
* |-. chains | ||
* | '-. subnetID | ||
* | '-. list | ||
|
@@ -352,6 +355,11 @@ type state struct { | |
subnetBaseDB database.Database | ||
subnetDB linkeddb.LinkedDB | ||
|
||
// Subnet ID --> Owner of the subnet | ||
subnetOwners map[ids.ID]fx.Owner | ||
subnetOwnerCache cache.Cacher[ids.ID, fxOwnerAndSize] // cache of subnetID -> owner if the entry is nil, it is not in the database | ||
subnetOwnerDB database.Database | ||
|
||
transformedSubnets map[ids.ID]*txs.Tx // map of subnetID -> transformSubnetTx | ||
transformedSubnetCache cache.Cacher[ids.ID, *txs.Tx] // cache of subnetID -> transformSubnetTx if the entry is nil, it is not in the database | ||
transformedSubnetDB database.Database | ||
|
@@ -420,6 +428,11 @@ type txAndStatus struct { | |
status status.Status | ||
} | ||
|
||
type fxOwnerAndSize struct { | ||
owner fx.Owner | ||
size int | ||
} | ||
|
||
func txSize(_ ids.ID, tx *txs.Tx) int { | ||
if tx == nil { | ||
return ids.IDLen + constants.PointerOverhead | ||
|
@@ -573,6 +586,18 @@ func newState( | |
|
||
subnetBaseDB := prefixdb.New(subnetPrefix, baseDB) | ||
|
||
subnetOwnerDB := prefixdb.New(subnetOwnerPrefix, baseDB) | ||
subnetOwnerCache, err := metercacher.New[ids.ID, fxOwnerAndSize]( | ||
"subnet_owner_cache", | ||
metricsReg, | ||
cache.NewSizedLRU[ids.ID, fxOwnerAndSize](execCfg.FxOwnerCacheSize, func(_ ids.ID, f fxOwnerAndSize) int { | ||
return ids.IDLen + f.size | ||
}), | ||
) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
transformedSubnetCache, err := metercacher.New( | ||
"transformed_subnet_cache", | ||
metricsReg, | ||
|
@@ -669,6 +694,10 @@ func newState( | |
subnetBaseDB: subnetBaseDB, | ||
subnetDB: linkeddb.NewDefault(subnetBaseDB), | ||
|
||
subnetOwners: make(map[ids.ID]fx.Owner), | ||
subnetOwnerDB: subnetOwnerDB, | ||
subnetOwnerCache: subnetOwnerCache, | ||
|
||
transformedSubnets: make(map[ids.ID]*txs.Tx), | ||
transformedSubnetCache: transformedSubnetCache, | ||
transformedSubnetDB: prefixdb.New(transformedSubnetPrefix, baseDB), | ||
|
@@ -819,24 +848,54 @@ func (s *state) AddSubnet(createSubnetTx *txs.Tx) { | |
} | ||
|
||
func (s *state) GetSubnetOwner(subnetID ids.ID) (fx.Owner, error) { | ||
if owner, exists := s.subnetOwners[subnetID]; exists { | ||
return owner, nil | ||
} | ||
|
||
if ownerAndSize, cached := s.subnetOwnerCache.Get(subnetID); cached { | ||
if ownerAndSize.owner == nil { | ||
return nil, database.ErrNotFound | ||
} | ||
return ownerAndSize.owner, nil | ||
} | ||
|
||
ownerBytes, err := s.subnetOwnerDB.Get(subnetID[:]) | ||
if err == nil { | ||
var owner fx.Owner | ||
if _, err := block.GenesisCodec.Unmarshal(ownerBytes, &owner); err != nil { | ||
return nil, err | ||
} | ||
s.subnetOwnerCache.Put(subnetID, fxOwnerAndSize{ | ||
owner: owner, | ||
size: len(ownerBytes), | ||
}) | ||
return owner, nil | ||
} | ||
if err != database.ErrNotFound { | ||
return nil, err | ||
} | ||
|
||
subnetIntf, _, err := s.GetTx(subnetID) | ||
dhrubabasu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if err != nil { | ||
return nil, fmt.Errorf( | ||
"%w %q: %w", | ||
ErrCantFindSubnet, | ||
subnetID, | ||
err, | ||
) | ||
if err == database.ErrNotFound { | ||
s.subnetOwnerCache.Put(subnetID, fxOwnerAndSize{}) | ||
} | ||
return nil, err | ||
} | ||
|
||
subnet, ok := subnetIntf.Unsigned.(*txs.CreateSubnetTx) | ||
if !ok { | ||
return nil, fmt.Errorf("%q %w", subnetID, errIsNotSubnet) | ||
} | ||
|
||
s.SetSubnetOwner(subnetID, subnet.Owner) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feels a bit weird (to be performing a write on the read)... But I think it's ok |
||
return subnet.Owner, nil | ||
} | ||
|
||
func (s *state) SetSubnetOwner(subnetID ids.ID, owner fx.Owner) { | ||
dhrubabasu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
s.subnetOwners[subnetID] = owner | ||
} | ||
|
||
func (s *state) GetSubnetTransformation(subnetID ids.ID) (*txs.Tx, error) { | ||
if tx, exists := s.transformedSubnets[subnetID]; exists { | ||
return tx, nil | ||
|
@@ -1683,6 +1742,7 @@ func (s *state) write(updateValidators bool, height uint64) error { | |
s.writeRewardUTXOs(), | ||
s.writeUTXOs(), | ||
s.writeSubnets(), | ||
s.writeSubnetOwners(), | ||
s.writeTransformedSubnets(), | ||
s.writeSubnetSupplies(), | ||
s.writeChains(), | ||
|
@@ -2273,6 +2333,29 @@ func (s *state) writeSubnets() error { | |
return nil | ||
} | ||
|
||
func (s *state) writeSubnetOwners() error { | ||
for subnetID, owner := range s.subnetOwners { | ||
subnetID := subnetID | ||
owner := owner | ||
Comment on lines
+2338
to
+2339
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought loop variables in go were created once and the value was updated with each iteration, so I thought we wouldn't need these copies here. I think it's safe to remove these lines but i could be wrong. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are correct, it is safe to remove but I'd like to keep them since it's easier to understand that this is correct There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the linter is going to yell at us because we are passing references to these values into functions. While it is true that those functions don't hold a reference to them... it feels like this is more clearly correct (until go 1.22) |
||
delete(s.subnetOwners, subnetID) | ||
|
||
ownerBytes, err := block.GenesisCodec.Marshal(block.Version, &owner) | ||
if err != nil { | ||
return fmt.Errorf("failed to marshal subnet owner: %w", err) | ||
} | ||
|
||
s.subnetOwnerCache.Put(subnetID, fxOwnerAndSize{ | ||
owner: owner, | ||
size: len(ownerBytes), | ||
}) | ||
|
||
if err := s.subnetOwnerDB.Put(subnetID[:], ownerBytes); err != nil { | ||
return fmt.Errorf("failed to write subnet owner: %w", err) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (s *state) writeTransformedSubnets() error { | ||
for subnetID, tx := range s.transformedSubnets { | ||
txID := tx.ID() | ||
|
Uh oh!
There was an error while loading. Please reload this page.