Skip to content
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

Closed
wants to merge 66 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
dfb74b9
introduced stakers cold attributes
abi87 Dec 6, 2023
a1fa20d
some more consolidation
abi87 Dec 6, 2023
e88b5b0
some more consolidation
abi87 Dec 6, 2023
146e4d2
removed code duplication
abi87 Dec 6, 2023
54098a1
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 7, 2023
096da56
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 9, 2023
81fa250
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 10, 2023
0e89791
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 11, 2023
3cb96d4
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 12, 2023
9b370c1
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 13, 2023
8275968
fix regression
abi87 Dec 13, 2023
749b4cc
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 13, 2023
c6edf3f
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 15, 2023
51e67fa
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 16, 2023
9437684
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 18, 2023
c5ef601
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 19, 2023
88a0060
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 20, 2023
54287cc
adding UTs for getStakerColdAttributes
abi87 Dec 20, 2023
e8305e2
some more UTs
abi87 Dec 20, 2023
c311437
renamed cold attributes to reward attributes
abi87 Dec 20, 2023
a6d02fa
some more use of staker reward attributes
abi87 Dec 20, 2023
8e24737
Merge remote-tracking branch 'upstream/dev' into pchain_drop_getTx_fr…
Dec 20, 2023
1255c4f
nits
abi87 Dec 20, 2023
de5c35c
nit
abi87 Dec 20, 2023
56474e5
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 20, 2023
1a8d48d
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Dec 27, 2023
e57b035
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 2, 2024
705d287
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 3, 2024
259cb65
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 4, 2024
bb6ce69
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 5, 2024
25285ed
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 8, 2024
3450224
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 11, 2024
b0f525b
added UTs
abi87 Jan 11, 2024
564cf01
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 12, 2024
b9939ba
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 15, 2024
b407679
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 16, 2024
5d7bd08
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 17, 2024
be4cd69
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 18, 2024
297a490
appease linter
abi87 Jan 18, 2024
98ffec0
Merge branch 'dev' into pchain_drop_getTx_from_execution_paths
abi87 Jan 19, 2024
61cfc54
fixed mock regeneration
abi87 Jan 19, 2024
60d932d
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Jan 26, 2024
f9074bb
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Feb 6, 2024
75e7183
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Feb 12, 2024
7e88b9f
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Feb 13, 2024
ce48a20
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Feb 15, 2024
66c3ff7
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Feb 19, 2024
4ee6cae
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Feb 25, 2024
0d8a51c
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Mar 4, 2024
4b1663a
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Mar 11, 2024
7712dea
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Mar 19, 2024
5327899
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Mar 21, 2024
c88b814
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Mar 26, 2024
744b147
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Mar 27, 2024
4137e6e
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Mar 29, 2024
06e32cd
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Apr 4, 2024
fe32ee9
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Apr 8, 2024
2fbde4b
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Apr 9, 2024
2b40578
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Apr 12, 2024
dfa9d30
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Apr 23, 2024
b546086
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 May 10, 2024
749d27a
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 May 22, 2024
6ef929e
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Jun 3, 2024
6018ab8
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Jun 11, 2024
ec4426c
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Jun 25, 2024
0dbabd7
Merge branch 'master' into pchain_drop_getTx_from_execution_paths
abi87 Jul 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions vms/platformvm/block/executor/proposal_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ func TestApricotProposalBlockTimeVerification(t *testing.T) {
StartTime: utx.StartTime(),
NextTime: chainTime,
EndTime: chainTime,
Priority: utx.CurrentPriority(),
Copy link
Contributor Author

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

}).Times(2)
currentStakersIt.EXPECT().Release()
onParentAccept.EXPECT().GetCurrentStakerIterator().Return(currentStakersIt, nil)
Expand Down
25 changes: 25 additions & 0 deletions vms/platformvm/state/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,31 @@ func (d *diff) GetCurrentStakerIterator() (StakerIterator, error) {
return d.currentStakerDiffs.GetStakerIterator(parentIterator), nil
}

func (d *diff) GetStakerColdAttributes(stakerID ids.ID) (*StakerColdAttributes, error) {
stakerTx, _, err := d.GetTx(stakerID)
if err != nil {
return nil, fmt.Errorf("failed to get next staker %s: %w", stakerID, err)
}
switch uStakerTx := stakerTx.Unsigned.(type) {
case txs.ValidatorTx:
return &StakerColdAttributes{
Stake: uStakerTx.Stake(),
Outputs: uStakerTx.Outputs(),
Shares: uStakerTx.Shares(),
ValidationRewardsOwner: uStakerTx.ValidationRewardsOwner(),
DelegationRewardsOwner: uStakerTx.DelegationRewardsOwner(),
}, nil
case txs.DelegatorTx:
return &StakerColdAttributes{
Stake: uStakerTx.Stake(),
Outputs: uStakerTx.Outputs(),
RewardsOwner: uStakerTx.RewardsOwner(),
}, nil
default:
return nil, fmt.Errorf("unexpected stakerTx type %T", uStakerTx)
}
}

func (d *diff) GetPendingValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) {
// If the validator was modified in this diff, return the modified
// validator.
Expand Down
45 changes: 45 additions & 0 deletions vms/platformvm/state/mock_state.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions vms/platformvm/state/staker.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/crypto/bls"
"github.com/ava-labs/avalanchego/vms/components/avax"
"github.com/ava-labs/avalanchego/vms/platformvm/fx"
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
)

Expand Down Expand Up @@ -121,3 +123,23 @@ func NewPendingStaker(txID ids.ID, staker txs.Staker) (*Staker, error) {
Priority: staker.PendingPriority(),
}, nil
}

// While Staker object contains a staker's hot attributes, likely to be used pretty often
// StakerColdAttributes contains a staker's cold attributes, rarely used, mostly when rewarding it.
// Note that both Staker and StakerAttribute content comes from the stakerTx creating the staker.
// In state.State we do have StakerMetadata information as well, which contains data about the stakers
// that are generated during staker's activity (mostly uptimes)
// TODO: consider moving delegatees reward here, out of StakersMetadata.
type StakerColdAttributes struct {
// common attributes
Stake []*avax.TransferableOutput
Outputs []*avax.TransferableOutput

// validators specific attributes
Shares uint32
ValidationRewardsOwner fx.Owner
DelegationRewardsOwner fx.Owner

// delegators specific attributes
RewardsOwner fx.Owner
}
27 changes: 27 additions & 0 deletions vms/platformvm/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ type Chain interface {

AddChain(createChainTx *txs.Tx)

GetStakerColdAttributes(stakerID ids.ID) (*StakerColdAttributes, error)

GetTx(txID ids.ID) (*txs.Tx, status.Status, error)
AddTx(tx *txs.Tx, status status.Status)
}
Expand Down Expand Up @@ -733,6 +735,31 @@ func (s *state) GetCurrentStakerIterator() (StakerIterator, error) {
return s.currentStakers.GetStakerIterator(), nil
}

func (s *state) GetStakerColdAttributes(stakerID ids.ID) (*StakerColdAttributes, error) {
stakerTx, _, err := s.GetTx(stakerID)
abi87 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, fmt.Errorf("failed to get next staker %s: %w", stakerID, err)
}
switch uStakerTx := stakerTx.Unsigned.(type) {
case txs.ValidatorTx:
return &StakerColdAttributes{
Stake: uStakerTx.Stake(),
Outputs: uStakerTx.Outputs(),
Shares: uStakerTx.Shares(),
ValidationRewardsOwner: uStakerTx.ValidationRewardsOwner(),
DelegationRewardsOwner: uStakerTx.DelegationRewardsOwner(),
}, nil
case txs.DelegatorTx:
return &StakerColdAttributes{
Stake: uStakerTx.Stake(),
Outputs: uStakerTx.Outputs(),
RewardsOwner: uStakerTx.RewardsOwner(),
}, nil
default:
return nil, fmt.Errorf("unexpected stakerTx type %T", uStakerTx)
}
}

func (s *state) GetPendingValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) {
return s.pendingStakers.GetValidator(subnetID, nodeID)
}
Expand Down
61 changes: 26 additions & 35 deletions vms/platformvm/txs/executor/proposal_tx_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,36 +363,36 @@ func (e *ProposalTxExecutor) RewardValidatorTx(tx *txs.RewardValidatorTx) error
return err
}

stakerTx, _, err := e.OnCommitState.GetTx(stakerToReward.TxID)
stakerAttributes, err := e.OnCommitState.GetStakerColdAttributes(stakerToReward.TxID)
if err != nil {
return fmt.Errorf("failed to get next removed staker tx: %w", err)
return fmt.Errorf("failed to get attributes for staker %d: %w", stakerToReward.TxID, err)
abi87 marked this conversation as resolved.
Show resolved Hide resolved
}

// Invariant: A [txs.DelegatorTx] does not also implement the
// [txs.ValidatorTx] interface.
switch uStakerTx := stakerTx.Unsigned.(type) {
case txs.ValidatorTx:
if err := e.rewardValidatorTx(uStakerTx, stakerToReward); err != nil {
switch {
case stakerToReward.Priority.IsPermissionedValidator():
// Invariant: Permissioned stakers are removed by the advancement of
// time and the current chain timestamp is == this staker's
// EndTime. This means only permissionless stakers should be
// left in the staker set.
return ErrShouldBePermissionlessStaker
case stakerToReward.Priority.IsCurrentValidator():
if err := e.rewardValidatorTx(stakerToReward, stakerAttributes); err != nil {
return err
}

// Handle staker lifecycle.
e.OnCommitState.DeleteCurrentValidator(stakerToReward)
e.OnAbortState.DeleteCurrentValidator(stakerToReward)
case txs.DelegatorTx:
if err := e.rewardDelegatorTx(uStakerTx, stakerToReward); err != nil {
case stakerToReward.Priority.IsCurrentDelegator():
if err := e.rewardDelegatorTx(stakerToReward, stakerAttributes); err != nil {
return err
}

// Handle staker lifecycle.
e.OnCommitState.DeleteCurrentDelegator(stakerToReward)
e.OnAbortState.DeleteCurrentDelegator(stakerToReward)
default:
// Invariant: Permissioned stakers are removed by the advancement of
// time and the current chain timestamp is == this staker's
// EndTime. This means only permissionless stakers should be
// left in the staker set.
return ErrShouldBePermissionlessStaker
return errors.New("unexpected staker type")
abi87 marked this conversation as resolved.
Show resolved Hide resolved
}

// If the reward is aborted, then the current supply should be decreased.
Expand All @@ -411,11 +411,11 @@ func (e *ProposalTxExecutor) RewardValidatorTx(tx *txs.RewardValidatorTx) error
return err
}

func (e *ProposalTxExecutor) rewardValidatorTx(uValidatorTx txs.ValidatorTx, validator *state.Staker) error {
func (e *ProposalTxExecutor) rewardValidatorTx(validator *state.Staker, valAttributes *state.StakerColdAttributes) error {
var (
txID = validator.TxID
stake = uValidatorTx.Stake()
outputs = uValidatorTx.Outputs()
stake = valAttributes.Stake
outputs = valAttributes.Outputs
// Invariant: The staked asset must be equal to the reward asset.
stakeAsset = stake[0].Asset
)
Expand All @@ -440,7 +440,7 @@ func (e *ProposalTxExecutor) rewardValidatorTx(uValidatorTx txs.ValidatorTx, val
// Provide the reward here
reward := validator.PotentialReward
if reward > 0 {
validationRewardsOwner := uValidatorTx.ValidationRewardsOwner()
validationRewardsOwner := valAttributes.ValidationRewardsOwner
outIntf, err := e.Fx.CreateOutput(reward, validationRewardsOwner)
if err != nil {
return fmt.Errorf("failed to create output: %w", err)
Expand Down Expand Up @@ -477,7 +477,7 @@ func (e *ProposalTxExecutor) rewardValidatorTx(uValidatorTx txs.ValidatorTx, val
return nil
}

delegationRewardsOwner := uValidatorTx.DelegationRewardsOwner()
delegationRewardsOwner := valAttributes.DelegationRewardsOwner
outIntf, err := e.Fx.CreateOutput(delegateeReward, delegationRewardsOwner)
if err != nil {
return fmt.Errorf("failed to create output: %w", err)
Expand Down Expand Up @@ -513,11 +513,11 @@ func (e *ProposalTxExecutor) rewardValidatorTx(uValidatorTx txs.ValidatorTx, val
return nil
}

func (e *ProposalTxExecutor) rewardDelegatorTx(uDelegatorTx txs.DelegatorTx, delegator *state.Staker) error {
func (e *ProposalTxExecutor) rewardDelegatorTx(delegator *state.Staker, delAttributes *state.StakerColdAttributes) error {
var (
txID = delegator.TxID
stake = uDelegatorTx.Stake()
outputs = uDelegatorTx.Outputs()
stake = delAttributes.Stake
outputs = delAttributes.Outputs
// Invariant: The staked asset must be equal to the reward asset.
stakeAsset = stake[0].Asset
)
Expand All @@ -544,29 +544,20 @@ func (e *ProposalTxExecutor) rewardDelegatorTx(uDelegatorTx txs.DelegatorTx, del
return fmt.Errorf("failed to get whether %s is a validator: %w", delegator.NodeID, err)
}

vdrTxIntf, _, err := e.OnCommitState.GetTx(validator.TxID)
valAttributes, err := e.OnCommitState.GetStakerColdAttributes(validator.TxID)
if err != nil {
return fmt.Errorf("failed to get whether %s is a validator: %w", delegator.NodeID, err)
}

// Invariant: Delegators must only be able to reference validator
// transactions that implement [txs.ValidatorTx]. All
// validator transactions implement this interface except the
// AddSubnetValidatorTx.
vdrTx, ok := vdrTxIntf.Unsigned.(txs.ValidatorTx)
if !ok {
return ErrWrongTxType
}

// Calculate split of reward between delegator/delegatee
delegateeReward, delegatorReward := reward.Split(delegator.PotentialReward, vdrTx.Shares())
delegateeReward, delegatorReward := reward.Split(delegator.PotentialReward, valAttributes.Shares)

utxosOffset := 0

// Reward the delegator here
reward := delegatorReward
if reward > 0 {
rewardsOwner := uDelegatorTx.RewardsOwner()
rewardsOwner := delAttributes.RewardsOwner
outIntf, err := e.Fx.CreateOutput(reward, rewardsOwner)
if err != nil {
return fmt.Errorf("failed to create output: %w", err)
Expand Down Expand Up @@ -622,7 +613,7 @@ func (e *ProposalTxExecutor) rewardDelegatorTx(uDelegatorTx txs.DelegatorTx, del
} else {
// For any validators who started prior to [CortinaTime], we issue the
// [delegateeReward] immediately.
delegationRewardsOwner := vdrTx.DelegationRewardsOwner()
delegationRewardsOwner := valAttributes.DelegationRewardsOwner
outIntf, err := e.Fx.CreateOutput(delegateeReward, delegationRewardsOwner)
if err != nil {
return fmt.Errorf("failed to create output: %w", err)
Expand Down
Loading