-
Notifications
You must be signed in to change notification settings - Fork 699
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
Drop explicit calls to chain.GetTx from txs execution paths #2431
Changes from 23 commits
dfb74b9
a1fa20d
e88b5b0
146e4d2
54098a1
096da56
81fa250
0e89791
3cb96d4
9b370c1
8275968
749b4cc
c6edf3f
51e67fa
9437684
c5ef601
88a0060
54287cc
e8305e2
c311437
a6d02fa
8e24737
1255c4f
de5c35c
56474e5
1a8d48d
e57b035
705d287
259cb65
bb6ce69
25285ed
3450224
b0f525b
564cf01
b9939ba
b407679
5d7bd08
be4cd69
297a490
98ffec0
61cfc54
60d932d
f9074bb
75e7183
7e88b9f
ce48a20
66c3ff7
4ee6cae
0d8a51c
4b1663a
7712dea
5327899
c88b814
744b147
4137e6e
06e32cd
fe32ee9
2fbde4b
2b40578
dfa9d30
b546086
749d27a
6ef929e
6018ab8
ec4426c
0dbabd7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,9 +32,7 @@ import ( | |
"github.com/ava-labs/avalanchego/utils/set" | ||
"github.com/ava-labs/avalanchego/vms/components/avax" | ||
"github.com/ava-labs/avalanchego/vms/components/keystore" | ||
"github.com/ava-labs/avalanchego/vms/platformvm/fx" | ||
"github.com/ava-labs/avalanchego/vms/platformvm/reward" | ||
"github.com/ava-labs/avalanchego/vms/platformvm/signer" | ||
"github.com/ava-labs/avalanchego/vms/platformvm/stakeable" | ||
"github.com/ava-labs/avalanchego/vms/platformvm/state" | ||
"github.com/ava-labs/avalanchego/vms/platformvm/status" | ||
|
@@ -86,16 +84,7 @@ var ( | |
type Service struct { | ||
vm *VM | ||
addrManager avax.AddressManager | ||
stakerAttributesCache *cache.LRU[ids.ID, *stakerAttributes] | ||
} | ||
|
||
// All attributes are optional and may not be filled for each stakerTx. | ||
type stakerAttributes struct { | ||
shares uint32 | ||
rewardsOwner fx.Owner | ||
validationRewardsOwner fx.Owner | ||
delegationRewardsOwner fx.Owner | ||
proofOfPossession *signer.ProofOfPossession | ||
Comment on lines
-76
to
-81
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 PR promotes this struct to |
||
stakerAttributesCache *cache.LRU[ids.ID, *state.StakerRewardAttributes] | ||
} | ||
|
||
// GetHeight returns the height of the last accepted block | ||
|
@@ -726,44 +715,19 @@ type GetCurrentValidatorsReply struct { | |
Validators []interface{} `json:"validators"` | ||
} | ||
|
||
func (s *Service) loadStakerTxAttributes(txID ids.ID) (*stakerAttributes, error) { | ||
// Lookup tx from the cache first. | ||
func (s *Service) loadStakerTxAttributes(txID ids.ID) (*state.StakerRewardAttributes, error) { | ||
// Lookup attributes from the cache first. | ||
attr, found := s.stakerAttributesCache.Get(txID) | ||
if found { | ||
return attr, nil | ||
} | ||
|
||
// Tx not available in cache; pull it from disk and populate the cache. | ||
tx, _, err := s.vm.state.GetTx(txID) | ||
// attributes not available in cache; pull them from disk and populate the cache. | ||
attr, err := s.vm.state.GetStakerRewardAttributes(txID) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
switch stakerTx := tx.Unsigned.(type) { | ||
case txs.ValidatorTx: | ||
var pop *signer.ProofOfPossession | ||
if staker, ok := stakerTx.(*txs.AddPermissionlessValidatorTx); ok { | ||
if s, ok := staker.Signer.(*signer.ProofOfPossession); ok { | ||
pop = s | ||
} | ||
} | ||
|
||
attr = &stakerAttributes{ | ||
shares: stakerTx.Shares(), | ||
validationRewardsOwner: stakerTx.ValidationRewardsOwner(), | ||
delegationRewardsOwner: stakerTx.DelegationRewardsOwner(), | ||
proofOfPossession: pop, | ||
} | ||
|
||
case txs.DelegatorTx: | ||
attr = &stakerAttributes{ | ||
rewardsOwner: stakerTx.RewardsOwner(), | ||
} | ||
|
||
default: | ||
return nil, fmt.Errorf("unexpected staker tx type %T", tx.Unsigned) | ||
} | ||
Comment on lines
-714
to
-737
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 logic is being moved to state_helper.go and made available to process |
||
|
||
s.stakerAttributesCache.Put(txID, attr) | ||
return attr, nil | ||
} | ||
|
@@ -856,7 +820,7 @@ func (s *Service) GetCurrentValidators(_ *http.Request, args *GetCurrentValidato | |
return err | ||
} | ||
|
||
shares := attr.shares | ||
shares := attr.Shares | ||
delegationFee := json.Float32(100 * float32(shares) / float32(reward.PercentDenominator)) | ||
|
||
uptime, err := s.getAPIUptime(currentStaker) | ||
|
@@ -869,14 +833,14 @@ func (s *Service) GetCurrentValidators(_ *http.Request, args *GetCurrentValidato | |
validationRewardOwner *platformapi.Owner | ||
delegationRewardOwner *platformapi.Owner | ||
) | ||
validationOwner, ok := attr.validationRewardsOwner.(*secp256k1fx.OutputOwners) | ||
validationOwner, ok := attr.ValidationRewardsOwner.(*secp256k1fx.OutputOwners) | ||
if ok { | ||
validationRewardOwner, err = s.getAPIOwner(validationOwner) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
delegationOwner, ok := attr.delegationRewardsOwner.(*secp256k1fx.OutputOwners) | ||
delegationOwner, ok := attr.DelegationRewardsOwner.(*secp256k1fx.OutputOwners) | ||
if ok { | ||
delegationRewardOwner, err = s.getAPIOwner(delegationOwner) | ||
if err != nil { | ||
|
@@ -894,7 +858,7 @@ func (s *Service) GetCurrentValidators(_ *http.Request, args *GetCurrentValidato | |
ValidationRewardOwner: validationRewardOwner, | ||
DelegationRewardOwner: delegationRewardOwner, | ||
DelegationFee: delegationFee, | ||
Signer: attr.proofOfPossession, | ||
Signer: attr.ProofOfPossession, | ||
} | ||
reply.Validators = append(reply.Validators, vdr) | ||
|
||
|
@@ -907,7 +871,7 @@ func (s *Service) GetCurrentValidators(_ *http.Request, args *GetCurrentValidato | |
if err != nil { | ||
return err | ||
} | ||
owner, ok := attr.rewardsOwner.(*secp256k1fx.OutputOwners) | ||
owner, ok := attr.RewardsOwner.(*secp256k1fx.OutputOwners) | ||
if ok { | ||
rewardOwner, err = s.getAPIOwner(owner) | ||
if err != nil { | ||
|
@@ -1064,15 +1028,15 @@ func (s *Service) GetPendingValidators(_ *http.Request, args *GetPendingValidato | |
return err | ||
} | ||
|
||
shares := attr.shares | ||
shares := attr.Shares | ||
delegationFee := json.Float32(100 * float32(shares) / float32(reward.PercentDenominator)) | ||
|
||
connected := s.vm.uptimeManager.IsConnected(nodeID, args.SubnetID) | ||
vdr := platformapi.PermissionlessValidator{ | ||
Staker: apiStaker, | ||
DelegationFee: delegationFee, | ||
Connected: connected, | ||
Signer: attr.proofOfPossession, | ||
Signer: attr.ProofOfPossession, | ||
} | ||
reply.Validators = append(reply.Validators, vdr) | ||
|
||
|
@@ -1957,17 +1921,12 @@ func (s *Service) GetBlockchainStatus(r *http.Request, args *GetBlockchainStatus | |
} | ||
|
||
func (s *Service) nodeValidates(blockchainID ids.ID) bool { | ||
chainTx, _, err := s.vm.state.GetTx(blockchainID) | ||
subnetID, err := s.vm.state.GetChainSubnet(blockchainID) | ||
if err != nil { | ||
return false | ||
} | ||
|
||
chain, ok := chainTx.Unsigned.(*txs.CreateChainTx) | ||
if !ok { | ||
return false | ||
} | ||
|
||
_, isValidator := s.vm.Validators.GetValidator(chain.SubnetID, s.vm.ctx.NodeID) | ||
_, isValidator := s.vm.Validators.GetValidator(subnetID, s.vm.ctx.NodeID) | ||
return isValidator | ||
} | ||
|
||
|
@@ -1984,15 +1943,14 @@ func (s *Service) chainExists(ctx context.Context, blockID ids.ID, chainID ids.I | |
} | ||
} | ||
|
||
tx, _, err := state.GetTx(chainID) | ||
if err == database.ErrNotFound { | ||
switch _, err := state.GetChainSubnet(chainID); { | ||
case err == nil: | ||
return true, nil | ||
case errors.Is(err, database.ErrNotFound): | ||
return false, nil | ||
} | ||
if err != nil { | ||
default: | ||
return false, err | ||
} | ||
_, ok = tx.Unsigned.(*txs.CreateChainTx) | ||
return ok, nil | ||
} | ||
|
||
// ValidatedByArgs is the arguments for calling ValidatedBy | ||
|
@@ -2340,12 +2298,12 @@ func (s *Service) GetStake(_ *http.Request, args *GetStakeArgs, response *GetSta | |
continue | ||
} | ||
|
||
tx, _, err := s.vm.state.GetTx(staker.TxID) | ||
stakerRewardAttributes, err := s.vm.state.GetStakerRewardAttributes(staker.TxID) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
stakedOuts = append(stakedOuts, getStakeHelper(tx, addrs, totalAmountStaked)...) | ||
stakedOuts = append(stakedOuts, getStakeHelper(stakerRewardAttributes.Stake, addrs, totalAmountStaked)...) | ||
} | ||
|
||
pendingStakerIterator, err := s.vm.state.GetPendingStakerIterator() | ||
|
@@ -2361,12 +2319,12 @@ func (s *Service) GetStake(_ *http.Request, args *GetStakeArgs, response *GetSta | |
continue | ||
} | ||
|
||
tx, _, err := s.vm.state.GetTx(staker.TxID) | ||
stakerRewardAttributes, err := s.vm.state.GetStakerRewardAttributes(staker.TxID) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
stakedOuts = append(stakedOuts, getStakeHelper(tx, addrs, totalAmountStaked)...) | ||
stakedOuts = append(stakedOuts, getStakeHelper(stakerRewardAttributes.Stake, addrs, totalAmountStaked)...) | ||
} | ||
|
||
response.Stakeds = newJSONBalanceMap(totalAmountStaked) | ||
|
@@ -2789,17 +2747,11 @@ func (s *Service) getAPIOwner(owner *secp256k1fx.OutputOwners) (*platformapi.Own | |
return apiOwner, nil | ||
} | ||
|
||
// Takes in a staker and a set of addresses | ||
// Takes in a slice of reward attributes and a set of addresses | ||
// Returns: | ||
// 1) The total amount staked by addresses in [addrs] | ||
// 2) The staked outputs | ||
func getStakeHelper(tx *txs.Tx, addrs set.Set[ids.ShortID], totalAmountStaked map[ids.ID]uint64) []avax.TransferableOutput { | ||
staker, ok := tx.Unsigned.(txs.PermissionlessStaker) | ||
if !ok { | ||
return nil | ||
} | ||
|
||
stake := staker.Stake() | ||
func getStakeHelper(stake []*avax.TransferableOutput, addrs set.Set[ids.ShortID], totalAmountStaked map[ids.ID]uint64) []avax.TransferableOutput { | ||
abi87 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
stakedOuts := make([]avax.TransferableOutput, 0, len(stake)) | ||
// Go through all of the staked outputs | ||
for _, output := range stake { | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -209,6 +209,10 @@ func (d *diff) GetCurrentStakerIterator() (StakerIterator, error) { | |||||||||||||||
return d.currentStakerDiffs.GetStakerIterator(parentIterator), nil | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func (d *diff) GetStakerRewardAttributes(stakerID ids.ID) (*StakerRewardAttributes, error) { | ||||||||||||||||
return getStakerRewardAttributes(d, stakerID) | ||||||||||||||||
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. Should this just be calling the parent state 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. In current implementation this is a "derivative" method. The recursion to parent state happens by 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 comment was around the implementation of this method on
Suggested change
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 don't think this is correct. |
||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func (d *diff) GetPendingValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) { | ||||||||||||||||
// If the validator was modified in this diff, return the modified | ||||||||||||||||
// validator. | ||||||||||||||||
|
@@ -330,6 +334,10 @@ func (d *diff) AddChain(createChainTx *txs.Tx) { | |||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func (d *diff) GetChainSubnet(chainID ids.ID) (ids.ID, error) { | ||||||||||||||||
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. Why are we allowing calling this method on a 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. In the API it's used over the diff too. See 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. Got it- I think we should call the parentState here too |
||||||||||||||||
return getChainSubnet(d, chainID) | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func (d *diff) GetTx(txID ids.ID) (*txs.Tx, status.Status, error) { | ||||||||||||||||
if tx, exists := d.addedTxs[txID]; exists { | ||||||||||||||||
return tx.tx, tx.status, nil | ||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needed for rewritten RewardStaker to pass