diff --git a/cmd/node/config/economics.toml b/cmd/node/config/economics.toml index 27c9f44d05f..343bff6bb98 100644 --- a/cmd/node/config/economics.toml +++ b/cmd/node/config/economics.toml @@ -28,7 +28,7 @@ TopUpFactor = 0.25 # fraction of value 0.25 - 25% [[RewardsSettings.RewardsConfigByEpoch]] - EpochEnable = 2 + EpochEnable = 4 LeaderPercentage = 0.1 #fraction of value 0.1 - 10% DeveloperPercentage = 0.3 #fraction of value 0.3 - 30% ProtocolSustainabilityPercentage = 0.1 #fraction of value 0.1 - 10% diff --git a/cmd/node/factory/structs.go b/cmd/node/factory/structs.go index d00f782ba7b..d5ffbbf899f 100644 --- a/cmd/node/factory/structs.go +++ b/cmd/node/factory/structs.go @@ -2198,8 +2198,7 @@ func newMetaBlockProcessor( }, StakingDataProvider: stakingDataProvider, - TopUpRewardFactor: economicsData.RewardsTopUpFactor(), - TopUpGradientPoint: economicsData.RewardsTopUpGradientPoint(), + RewardsHandler: economicsData, EconomicsDataProvider: economicsDataProvider, EpochEnableV2: systemSCConfig.StakingSystemSCConfig.StakingV2Epoch, } diff --git a/epochStart/metachain/rewardsCreatorProxy.go b/epochStart/metachain/rewardsCreatorProxy.go index f394348550e..a3d5d3a5da0 100644 --- a/epochStart/metachain/rewardsCreatorProxy.go +++ b/epochStart/metachain/rewardsCreatorProxy.go @@ -25,8 +25,7 @@ type RewardsCreatorProxyArgs struct { BaseRewardsCreatorArgs StakingDataProvider epochStart.StakingDataProvider EconomicsDataProvider epochStart.EpochEconomicsDataProvider - TopUpRewardFactor float64 - TopUpGradientPoint *big.Int + RewardsHandler process.RewardsHandler EpochEnableV2 uint32 } @@ -184,8 +183,7 @@ func (rcp *rewardsCreatorProxy) createRewardsCreatorV2() (*rewardsCreatorV2, err BaseRewardsCreatorArgs: rcp.args.BaseRewardsCreatorArgs, StakingDataProvider: rcp.args.StakingDataProvider, EconomicsDataProvider: rcp.args.EconomicsDataProvider, - TopUpRewardFactor: rcp.args.TopUpRewardFactor, - TopUpGradientPoint: rcp.args.TopUpGradientPoint, + RewardsHandler: rcp.args.RewardsHandler, } return NewRewardsCreatorV2(argsV2) diff --git a/epochStart/metachain/rewardsCreatorProxy_test.go b/epochStart/metachain/rewardsCreatorProxy_test.go index 3008d337c0d..9ddc19e4c88 100644 --- a/epochStart/metachain/rewardsCreatorProxy_test.go +++ b/epochStart/metachain/rewardsCreatorProxy_test.go @@ -14,6 +14,7 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/marshal" + "github.com/ElrondNetwork/elrond-go/testscommon/economicsmocks" "github.com/stretchr/testify/require" ) @@ -352,12 +353,21 @@ func createDefaultBlockBody() *block.Body { func createDefaultRewardsCreatorProxyArgs() RewardsCreatorProxyArgs { rewardsTopUpGradientPoint, _ := big.NewInt(0).SetString("3000000000000000000000000", 10) + + rewardsHandler := &economicsmocks.EconomicsHandlerStub{ + RewardsTopUpGradientPointCalled: func() *big.Int { + return rewardsTopUpGradientPoint + }, + RewardsTopUpFactorCalled: func() float64 { + return 0.25 + }, + } + return RewardsCreatorProxyArgs{ BaseRewardsCreatorArgs: getBaseRewardsArguments(), StakingDataProvider: &mock.StakingDataProviderStub{}, EconomicsDataProvider: NewEpochEconomicsStatistics(), - TopUpRewardFactor: 0.25, - TopUpGradientPoint: rewardsTopUpGradientPoint, + RewardsHandler: rewardsHandler, } } diff --git a/epochStart/metachain/rewardsV2.go b/epochStart/metachain/rewardsV2.go index 66a3af20965..1f8cb14b057 100644 --- a/epochStart/metachain/rewardsV2.go +++ b/epochStart/metachain/rewardsV2.go @@ -31,16 +31,14 @@ type RewardsCreatorArgsV2 struct { BaseRewardsCreatorArgs StakingDataProvider epochStart.StakingDataProvider EconomicsDataProvider epochStart.EpochEconomicsDataProvider - TopUpRewardFactor float64 - TopUpGradientPoint *big.Int + RewardsHandler process.RewardsHandler } type rewardsCreatorV2 struct { *baseRewardsCreator stakingDataProvider epochStart.StakingDataProvider economicsDataProvider epochStart.EpochEconomicsDataProvider - topUpRewardFactor float64 - topUpGradientPoint *big.Int + rewardsHandler process.RewardsHandler } // NewRewardsCreatorV2 creates a new rewards creator object @@ -56,19 +54,15 @@ func NewRewardsCreatorV2(args RewardsCreatorArgsV2) (*rewardsCreatorV2, error) { if check.IfNil(args.EconomicsDataProvider) { return nil, epochStart.ErrNilEconomicsDataProvider } - if args.TopUpGradientPoint.Cmp(zero) < 0 { - return nil, epochStart.ErrInvalidRewardsTopUpGradientPoint - } - if args.TopUpRewardFactor < 0 || args.TopUpRewardFactor > 1 { - return nil, epochStart.ErrInvalidRewardsTopUpFactor + if check.IfNil(args.RewardsHandler) { + return nil, epochStart.ErrNilRewardsHandler } rc := &rewardsCreatorV2{ baseRewardsCreator: brc, economicsDataProvider: args.EconomicsDataProvider, stakingDataProvider: args.StakingDataProvider, - topUpRewardFactor: args.TopUpRewardFactor, - topUpGradientPoint: args.TopUpGradientPoint, + rewardsHandler: args.RewardsHandler, } return rc, nil @@ -387,21 +381,34 @@ func (rc *rewardsCreatorV2) computeTopUpRewards(totalToDistribute *big.Int, tota return big.NewInt(0) } + log.Debug("computeTopUpRewards", "totalToDistribute", totalToDistribute.String()) + log.Debug("computeTopUpRewards", "totalTopUpEligible", totalTopUpEligible.String()) + // k = c * economics.TotalToDistribute, c = top-up reward factor (constant) - k := core.GetIntTrimmedPercentageOfValue(totalToDistribute, rc.topUpRewardFactor) + k := core.GetIntTrimmedPercentageOfValue(totalToDistribute, rc.rewardsHandler.RewardsTopUpFactor()) + log.Debug("computeTopUpRewards", "topUpFactor", rc.rewardsHandler.RewardsTopUpFactor()) + log.Debug("computeTopUpRewards", "k", k.String()) + // p is the cumulative eligible stake where rewards per day reach 1/2 of k (constant) // x/p - argument for atan totalTopUpEligibleFloat := big.NewFloat(0).SetInt(totalTopUpEligible) - topUpGradientPointFloat := big.NewFloat(0).SetInt(rc.topUpGradientPoint) + topUpGradientPointFloat := big.NewFloat(0).SetInt(rc.rewardsHandler.RewardsTopUpGradientPoint()) + log.Debug("computeTopUpRewards", "topUpGradientPoint", rc.rewardsHandler.RewardsTopUpGradientPoint().String()) floatArg, _ := big.NewFloat(0).Quo(totalTopUpEligibleFloat, topUpGradientPointFloat).Float64() + log.Debug("computeTopUpRewards", "x/p", floatArg) + // atan(x/p) res1 := math.Atan(floatArg) + log.Debug("computeTopUpRewards", "atan(x/p)", res1) // 2*k/pi res2 := big.NewFloat(0).SetInt(big.NewInt(0).Mul(k, big.NewInt(2))) res2 = big.NewFloat(0).Quo(res2, big.NewFloat(math.Pi)) + log.Debug("computeTopUpRewards", "2k/pi", res2) + // topUpReward:= (2*k/pi)*atan(x/p) topUpRewards, _ := big.NewFloat(0).Mul(big.NewFloat(res1), res2).Int(nil) + log.Debug("computeTopUpRewards", "topUpRewards", topUpRewards.String()) return topUpRewards } diff --git a/epochStart/metachain/rewardsV2_test.go b/epochStart/metachain/rewardsV2_test.go index 65c30ceb726..1ebeac6e875 100644 --- a/epochStart/metachain/rewardsV2_test.go +++ b/epochStart/metachain/rewardsV2_test.go @@ -17,6 +17,7 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/testscommon/economicsmocks" "github.com/stretchr/testify/require" ) @@ -72,37 +73,15 @@ func TestNewRewardsCreator_NilEconomicsDataProvider(t *testing.T) { require.Equal(t, epochStart.ErrNilEconomicsDataProvider, err) } -func TestNewRewardsCreator_NegativeGradientPointShouldErr(t *testing.T) { +func TestNewRewardsCreator_NilRewardsHandlerShouldErr(t *testing.T) { t.Parallel() args := getRewardsCreatorV2Arguments() - args.TopUpGradientPoint = big.NewInt(-1) + args.RewardsHandler = nil rwd, err := NewRewardsCreatorV2(args) require.True(t, check.IfNil(rwd)) - require.Equal(t, epochStart.ErrInvalidRewardsTopUpGradientPoint, err) -} - -func TestNewRewardsCreator_NegativeTopUpRewardFactorShouldErr(t *testing.T) { - t.Parallel() - - args := getRewardsCreatorV2Arguments() - args.TopUpRewardFactor = -1 - - rwd, err := NewRewardsCreatorV2(args) - require.True(t, check.IfNil(rwd)) - require.Equal(t, epochStart.ErrInvalidRewardsTopUpFactor, err) -} - -func TestNewRewardsCreator_SupraUnitaryTopUpRewardFactorShouldErr(t *testing.T) { - t.Parallel() - - args := getRewardsCreatorV2Arguments() - args.TopUpRewardFactor = 1.5 - - rwd, err := NewRewardsCreatorV2(args) - require.True(t, check.IfNil(rwd)) - require.Equal(t, epochStart.ErrInvalidRewardsTopUpFactor, err) + require.Equal(t, epochStart.ErrNilRewardsHandler, err) } func TestNewRewardsCreatorOK(t *testing.T) { @@ -588,7 +567,7 @@ func TestNewRewardsCreatorV2_computeTopUpRewards(t *testing.T) { require.NotNil(t, rwd) totalToDistribute, _ := big.NewInt(0).SetString("3000000000000000000000", 10) - topUpRewardsLimit := core.GetApproximatePercentageOfValue(totalToDistribute, rwd.topUpRewardFactor) + topUpRewardsLimit := core.GetApproximatePercentageOfValue(totalToDistribute, rwd.rewardsHandler.RewardsTopUpFactor()) totalTopUpEligible, _ := big.NewInt(0).SetString("2000000000000000000000000", 10) topUpRewards := rwd.computeTopUpRewards(totalToDistribute, totalTopUpEligible) @@ -1789,23 +1768,41 @@ func TestNewRewardsCreatorV2_CreateRewardsMiniBlocks2169Nodes(t *testing.T) { func getRewardsCreatorV2Arguments() RewardsCreatorArgsV2 { rewardsTopUpGradientPoint, _ := big.NewInt(0).SetString("3000000000000000000000000", 10) + topUpRewardFactor := 0.25 + + rewardsHandler := &economicsmocks.EconomicsHandlerStub{ + RewardsTopUpGradientPointCalled: func() *big.Int { + return big.NewInt(0).Set(rewardsTopUpGradientPoint) + }, + RewardsTopUpFactorCalled: func() float64 { + return topUpRewardFactor + }, + } return RewardsCreatorArgsV2{ BaseRewardsCreatorArgs: getBaseRewardsArguments(), StakingDataProvider: &mock.StakingDataProviderStub{}, EconomicsDataProvider: NewEpochEconomicsStatistics(), - TopUpRewardFactor: 0.25, - TopUpGradientPoint: rewardsTopUpGradientPoint, + RewardsHandler: rewardsHandler, } } func getRewardsCreatorV35Arguments() RewardsCreatorArgsV2 { rewardsTopUpGradientPoint, _ := big.NewInt(0).SetString("2000000000000000000000000", 10) + topUpRewardFactor := 0.5 + + rewardsHandler := &economicsmocks.EconomicsHandlerStub{ + RewardsTopUpGradientPointCalled: func() *big.Int { + return big.NewInt(0).Set(rewardsTopUpGradientPoint) + }, + RewardsTopUpFactorCalled: func() float64 { + return topUpRewardFactor + }, + } return RewardsCreatorArgsV2{ BaseRewardsCreatorArgs: getBaseRewardsArguments(), StakingDataProvider: &mock.StakingDataProviderStub{}, EconomicsDataProvider: NewEpochEconomicsStatistics(), - TopUpRewardFactor: 0.5, - TopUpGradientPoint: rewardsTopUpGradientPoint, + RewardsHandler: rewardsHandler, } } diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index ab514fef84d..6832fd05b09 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -1915,8 +1915,7 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { UserAccountsDB: tpn.AccntState, }, StakingDataProvider: stakingDataProvider, - TopUpGradientPoint: tpn.EconomicsData.RewardsTopUpGradientPoint(), - TopUpRewardFactor: tpn.EconomicsData.RewardsTopUpFactor(), + RewardsHandler: tpn.EconomicsData, EconomicsDataProvider: economicsDataProvider, EpochEnableV2: StakingV2Epoch, }