diff --git a/api/service/metrics/service.go b/api/service/metrics/service.go index 52782402b..5807d130f 100644 --- a/api/service/metrics/service.go +++ b/api/service/metrics/service.go @@ -19,6 +19,8 @@ import ( // Constants for metrics service. const ( + BalanceScale int = 18 + BalancePrecision int = 13 ConnectionsNumberPush int = 0 BlockHeightPush int = 1 NodeBalancePush int = 2 @@ -142,6 +144,23 @@ func (s *Service) Run() { return } +// FormatBalanace formats big.Int balance with precision. +func FormatBalance(balance *big.Int) float64 { + stringBalance := balance.String() + if len(stringBalance) < BalanceScale { + return 0.0 + } + if len(stringBalance) == BalanceScale { + stringBalance = "0."+stringBalance[len(stringBalance)-BalanceScale:len(stringBalance)-BalancePrecision] + } else { + stringBalance = stringBalance[:len(stringBalance)-BalanceScale]+"."+stringBalance[len(stringBalance)-BalanceScale:len(stringBalance)-BalancePrecision] + } + if res, err := strconv.ParseFloat(stringBalance, 64); err == nil { + return res + } + return 0.0 +} + // UpdateBlockHeight updates block height. func UpdateBlockHeight(blockHeight uint64) { blockHeightCounter.Add(float64(blockHeight) - float64(curBlockHeight)) @@ -152,14 +171,14 @@ func UpdateBlockHeight(blockHeight uint64) { // UpdateNodeBalance updates node balance. func UpdateNodeBalance(balance *big.Int) { - nodeBalanceCounter.Add(float64(balance.Uint64()) - float64(curBalance.Uint64())) + nodeBalanceCounter.Add(FormatBalance(balance) - FormatBalance(curBalance)) curBalance = balance metricsPush <- NodeBalancePush } // UpdateBlockReward updates block reward. func UpdateBlockReward(blockReward *big.Int) { - blockRewardGauge.Set(float64(blockReward.Uint64())) + blockRewardGauge.Set(FormatBalance(blockReward)) lastBlockReward = blockReward metricsPush <- BlockRewardPush } diff --git a/consensus/consensus.go b/consensus/consensus.go index 596a57d41..3a2e331f3 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -159,6 +159,9 @@ type Consensus struct { // If true, this consensus will not propose view change. disableViewChange bool + + // last node block reward for metrics + lastBlockReward *big.Int } // SetCommitDelay sets the commit message delay. If set to non-zero, @@ -226,6 +229,11 @@ func (consensus *Consensus) RewardThreshold() int { return len(consensus.PublicKeys) * 9 / 10 } +// GetBlockReward returns last node block reward +func (consensus *Consensus) GetBlockReward() *big.Int { + return consensus.lastBlockReward +} + // StakeInfoFinder finds the staking account for the given consensus key. type StakeInfoFinder interface { // FindStakeInfoByNodeKey returns a list of staking information matching @@ -281,6 +289,7 @@ func New(host p2p.Host, ShardID uint32, leader p2p.Peer, blsPriKey *bls.SecretKe consensus.commitFinishChan = make(chan uint64) consensus.ReadySignal = make(chan struct{}) + consensus.lastBlockReward = big.NewInt(0) // channel for receiving newly generated VDF consensus.RndChannel = make(chan [vdfAndSeedSize]byte) @@ -294,36 +303,37 @@ func New(host p2p.Host, ShardID uint32, leader p2p.Peer, blsPriKey *bls.SecretKe // accumulateRewards credits the coinbase of the given block with the mining // reward. The total reward consists of the static block reward and rewards for // included uncles. The coinbase of each uncle block is also rewarded. +// Returns node block reward or error. func accumulateRewards( - bc consensus_engine.ChainReader, state *state.DB, header *types.Header, -) error { + bc consensus_engine.ChainReader, state *state.DB, header *types.Header, nodeAddress common.Address, +) (*big.Int, error) { blockNum := header.Number.Uint64() if blockNum == 0 { // Epoch block has no parent to reward. - return nil + return nil, nil } // TODO ek – retrieving by parent number (blockNum - 1) doesn't work, // while it is okay with hash. Sounds like DB inconsistency. // Figure out why. parentHeader := bc.GetHeaderByHash(header.ParentHash) if parentHeader == nil { - return ctxerror.New("cannot find parent block header in DB", + return nil, ctxerror.New("cannot find parent block header in DB", "parentHash", header.ParentHash) } if parentHeader.Number.Cmp(common.Big0) == 0 { // Parent is an epoch block, // which is not signed in the usual manner therefore rewards nothing. - return nil + return nil, nil } parentShardState, err := bc.ReadShardState(parentHeader.Epoch) if err != nil { - return ctxerror.New("cannot read shard state", + return nil, ctxerror.New("cannot read shard state", "epoch", parentHeader.Epoch, ).WithCause(err) } parentCommittee := parentShardState.FindCommitteeByID(parentHeader.ShardID) if parentCommittee == nil { - return ctxerror.New("cannot find shard in the shard state", + return nil, ctxerror.New("cannot find shard in the shard state", "parentBlockNumber", parentHeader.Number, "shardID", parentHeader.ShardID, ) @@ -333,24 +343,24 @@ func accumulateRewards( committerKey := new(bls.PublicKey) err := member.BlsPublicKey.ToLibBLSPublicKey(committerKey) if err != nil { - return ctxerror.New("cannot convert BLS public key", + return nil, ctxerror.New("cannot convert BLS public key", "blsPublicKey", member.BlsPublicKey).WithCause(err) } committerKeys = append(committerKeys, committerKey) } mask, err := bls_cosi.NewMask(committerKeys, nil) if err != nil { - return ctxerror.New("cannot create group sig mask").WithCause(err) + return nil, ctxerror.New("cannot create group sig mask").WithCause(err) } if err := mask.SetMask(header.LastCommitBitmap); err != nil { - return ctxerror.New("cannot set group sig mask bits").WithCause(err) + return nil, ctxerror.New("cannot set group sig mask bits").WithCause(err) } totalAmount := big.NewInt(0) var accounts []common.Address signers := []string{} for idx, member := range parentCommittee.NodeList { if signed, err := mask.IndexEnabled(idx); err != nil { - return ctxerror.New("cannot check for committer bit", + return nil, ctxerror.New("cannot check for committer bit", "committerIndex", idx, ).WithCause(err) } else if signed { @@ -359,11 +369,15 @@ func accumulateRewards( } numAccounts := big.NewInt(int64(len(accounts))) last := new(big.Int) + nodeReward := big.NewInt(0) for i, account := range accounts { cur := new(big.Int) cur.Mul(BlockReward, big.NewInt(int64(i+1))).Div(cur, numAccounts) diff := new(big.Int).Sub(cur, last) signers = append(signers, common2.MustAddressToBech32(account)) + if account == nodeAddress { + nodeReward = diff + } state.AddBalance(account, diff) totalAmount = new(big.Int).Add(totalAmount, diff) last = cur @@ -373,7 +387,7 @@ func accumulateRewards( Str("TotalAmount", totalAmount.String()). Strs("Signers", signers). Msg("[Block Reward] Successfully paid out block reward") - return nil + return nodeReward, nil } // GenesisStakeInfoFinder is a stake info finder implementation using only diff --git a/consensus/consensus_service.go b/consensus/consensus_service.go index 5a97f3efa..cb066422d 100644 --- a/consensus/consensus_service.go +++ b/consensus/consensus_service.go @@ -287,9 +287,11 @@ func (consensus *Consensus) VerifySeal(chain consensus_engine.ChainReader, heade func (consensus *Consensus) Finalize(chain consensus_engine.ChainReader, header *types.Header, state *state.DB, txs []*types.Transaction, receipts []*types.Receipt) (*types.Block, error) { // Accumulate any block and uncle rewards and commit the final state root // Header seems complete, assemble into a block and return - if err := accumulateRewards(chain, state, header); err != nil { + blockReward, err := accumulateRewards(chain, state, header, consensus.SelfAddress) + if err != nil { return nil, ctxerror.New("cannot pay block reward").WithCause(err) } + consensus.lastBlockReward = blockReward header.Root = state.IntermediateRoot(false) return types.NewBlock(header, txs, receipts), nil } diff --git a/internal/configs/sharding/mainnet.go b/internal/configs/sharding/mainnet.go index 9ad1f9596..1f78b5d98 100644 --- a/internal/configs/sharding/mainnet.go +++ b/internal/configs/sharding/mainnet.go @@ -72,7 +72,7 @@ func (ms mainnetSchedule) ConsensusRatio() float64 { var mainnetReshardingEpoch = []*big.Int{big.NewInt(0), big.NewInt(mainnetV1Epoch)} var mainnetV0 = MustNewInstance(4, 150, 112, genesis.HarmonyAccounts, genesis.FoundationalNodeAccounts, mainnetReshardingEpoch) var mainnetV1 = MustNewInstance(4, 152, 112, genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1, mainnetReshardingEpoch) -var mainnetV2 = MustNewInstance(4, 160, 112, genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV2, mainnetReshardingEpoch) +var mainnetV2 = MustNewInstance(4, 200, 148, genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV2, mainnetReshardingEpoch) //var mainnetV2 = MustNewInstance(8, 200, 100) //var mainnet6400 = MustNewInstance(16, 400, 50) diff --git a/internal/genesis/foundational.go b/internal/genesis/foundational.go index eb7d1153b..6934a11db 100644 --- a/internal/genesis/foundational.go +++ b/internal/genesis/foundational.go @@ -455,9 +455,9 @@ var FoundationalNodeAccountsV2 = []DeployAccount{ {Index: "130", Address: "one1hrg76d5743k5x8jmyu4zyn232fzdexf06w32s3", BlsPublicKey: "930590243131160f8007ddf0a8107c01c5600c57b8b107ae21a9c0a7e71ebdbcf820230f7cd2a00eeb2777f9f62fed03"}, {Index: "131", Address: "one12kdc0fqxne5f3394wrwadxq9yfaquyxgtaed3q", BlsPublicKey: "826f98d1f8ce8751dac0441888f4b4f1190ec90691d5e40110c39068d0f95ea9cca8efe23d0f7a865bd9ed37ebf38d12"}, {Index: "132", Address: "one1h2dynptqmtgdfg9fgpd8dvmv8scupkgtzapx4l", BlsPublicKey: "814843ee8475adb2245027e9531e036c4135cf25a1051d5ea97f9f9cea506503e4a83a49bea1ee40e5b9a9c5f55f8014"}, - {Index: "133", Address: "one176nrt06rjmg9qunhf0z7wdhphdjtpq94y73d7s", BlsPublicKey: "577ff3c1e04184eb28ec4ea1f0ca0fe8e60723cdd0bb4a637f2ed4b809f967b76b990417ca3e7a3de5f38de850d27a0c"}, + {Index: "133", Address: "one1l4yrxjz8ugwjdcxrm5snwgmgk8few9v2q2xv8h", BlsPublicKey: "aa37a8ad8fb42a5b1413be9ae5b053e7a47d2f36a11a1e7ba74c4b338919c9c76eca3a6332c06fbbd161a6aef20e9a0b"}, {Index: "134", Address: "one1qndvm7y956s00ewfmtt6vf5qpzl7f3pa3q4lsa", BlsPublicKey: "4566f15e6616b56b1c5c877846def0f20c4a60e3f13710a9c021f54a63af68330fbcf870c9c4bc12251522d77b1d6219"}, - {Index: "135", Address: "one1ahw70lq9sqqygs8f7zdrvw7zd796w5n48hc5xh", BlsPublicKey: "f0d6a1d78c4817e451fb242b7501b23a9e9b5214e6ae8695a00e344a2f6662dad96baeb4f983d5613404795fae71e80d"}, + {Index: "135", Address: "one173275rcmnj8q2yxcqpwc8383hqmzudmxltu3fg", BlsPublicKey: "17cbb66d2ca63f15e9d808b0dcdeb8c612c36107d401d0797a70627935239b4117718349cb3a977e47078b19bbba9892"}, {Index: "136", Address: "one1g2h035trcm7dshsq9nqxzacr08ane0gx7kwjwp", BlsPublicKey: "fdae69318dbf9c54f8b0e841b5cf0cf2f733229e29e2bc4966fddc1df2811159164b4c2d9bb4c7cf7a060847a77fcd81"}, {Index: "137", Address: "one15qcw9x6q43r95q8udef5p2rkzu8hdkhljvxjww", BlsPublicKey: "c20abcb18d6ea49c40a70591de6b6622d0f74161eadb64765a2aaabaaa887e631a54affe5a4fdf7458c9d4b3bd99da03"}, {Index: "138", Address: "one1cx5dtllm52wrur463t04szxqc6mpjdn0u8h4qt", BlsPublicKey: "1f53d21ef9baec26bd484ee8e17f852df71c6bf7f3313a99c9882d553f0c1361bda7af2415caf62d0c7566750ed7bc8e"}, @@ -502,7 +502,7 @@ var FoundationalNodeAccountsV2 = []DeployAccount{ {Index: "177", Address: "one1cz4vfaf2j99h759c69l74yk4wfk6mxzrkg49su", BlsPublicKey: "0e079c8d8ce3369cd252ffd8b7ce06fbd8f607bfccd3ef91f9cf4868c0fa7785e84e8f1f666a72321f938c2d30482e8a"}, {Index: "178", Address: "one1spnnh4excv6uvwzx8mj64w6n8wt2k6z9ndphsg", BlsPublicKey: "733c974600c08a368c634aaf4044feacb8dd274e2dce08e1a9c9490dded88129b52609d0e7113ca9736b82387f710004"}, {Index: "179", Address: "one18275j9m2q377cpgkwkea838cdva2p6a4837xlw", BlsPublicKey: "0c9b550925208cdf1a6d916579e96f485a14bd5bcbba23e0b719adb68a0062de96755d5fe8a47669eac60ce3fbb1e606"}, - {Index: "180", Address: "one1myf9fq61t4f01c5nfuuhe3kjlr3fn93xy26xer", BlsPublicKey: "6689f75ae2a7afb458af4505516f1656e99e0356b7c06cd8b8854f3bf0ffcf350c572cf6b5c4614865ea626c8a22c70c"}, + {Index: "180", Address: "one1myf9fq6lt4f0lc5nfuuhe3kjlr3fn93xy26xer", BlsPublicKey: "6689f75ae2a7afb458af4505516f1656e99e0356b7c06cd8b8854f3bf0ffcf350c572cf6b5c4614865ea626c8a22c70c"}, {Index: "181", Address: "one1c336y6s99zudg637tdlrnd4amlcd6c8s00pcrf", BlsPublicKey: "cd25ebf073520521577f009c1efdcaee10bc890040df9f9c53ee4f8882821b27c15cefbff00cace98e1d6d13070a1196"}, {Index: "182", Address: "one1k57u35ycut268vdn054tf3h24pewc0e6yz9tej", BlsPublicKey: "23f983c8ea8467040f63a53f1f262a871956c510dc6b2484ccee57552dea27a211f3ba4a3050baf35957e2d380096484"}, {Index: "183", Address: "one1933f2dpa5a7ezh2q6ul5nakd26tynn4l75pt6h", BlsPublicKey: "7fa5a39d171f5ceb2c58571731d6273e55420722984caaf17607a6ebdc18e32350406f5e537474a26cb31b9c97504a04"}, @@ -514,4 +514,20 @@ var FoundationalNodeAccountsV2 = []DeployAccount{ {Index: "189", Address: "one1yuqws7le57naq90w2z42k3undccy8nh7wdmuhz", BlsPublicKey: "2611e59381f2f117746ea12cea76a09ba5895bc503d4bc5561b546d673ccc4fff854aea26e9c43c3682444c25396490a"}, {Index: "190", Address: "one19us7lt0ee7t2t2vy55ss7xnet6wx3myuny565q", BlsPublicKey: "1afea99e56b80d68ee8c7b4ddb3d7b6144dda350c90f8b11c0acb6d404a651fe8a562467f74fa60aee83c9a9b8a3de8e"}, {Index: "191", Address: "one13fnskkve55zhqr3nwrmxp2f8yxyjxagpwhf7xh", BlsPublicKey: "42d5aeaa2e9913cd54c95882e5343d8b1b15314dd2baa694fa77b79ec52727d98f602906e115a872a446f110797bdd90"}, + {Index: "192", Address: "one1fuhwmxdr4zulfm0lxndp7lgrstrmfpdam0w7x9", BlsPublicKey: "d0e5396e4eca701674e30acedb7ae2cf440fd429a17a08439946c711cb52fea53557f92230833b7ff5e96f297e9b368b"}, + {Index: "193", Address: "one19jk2rkkww7seu0prw58khw0whn73r2em47d8z9", BlsPublicKey: "c803c57b1f3b834adfe73a92d3ae3b4fb1f70902b1a955f4c75b685322e14013b3d67d77b6a47621c84c0b94cb299b18"}, + {Index: "194", Address: "one15vkywmeq9l0hx93zvgrdd58nyvd9yjd7l3myyx", BlsPublicKey: "0bfc81ad64427416b0495179a8744b0303e32e90d649e9db02c9c5df6ff647df9b377c82feaba8bf935b71c846be8b13"}, + {Index: "195", Address: "one127p7l3xcsslutld9d3pmj44vkza6048dtev2vj", BlsPublicKey: "3b7b6a3246c956f98af384820bf451b65b9e8770319cf7d7c37958a0f678682f47dcd9a120a27405a41e2d9186cf7886"}, + {Index: "196", Address: "one1nvct6um8vz698pz7rjqe7m2gcqezqek3h7dc6c", BlsPublicKey: "1c9c46000feb86456fe349fc355d9a6e70a0d125292deafd5490543df0789b07b4de420c5774f35a3115dbf7fe184383"}, + {Index: "197", Address: "one137x3qnxekuew5v74myypk4pjr3cuzldg639n4k", BlsPublicKey: "23cc21507963af79a385dcf4fdc915330eaea4b8e4346d53292b06fc5de5d886ed87d8aa2d0ef36703b40276d2404114"}, + {Index: "198", Address: "one1jd3v62xz8syc0c466vcrq9q5ylxt8pkzzptkxn", BlsPublicKey: "cc0fbd9bee704cb4c4117a1dd2ffb6e0f541a174e520eca7f101a6e8fcd231095e6779f59948db95efbb9cbb65647411"}, + {Index: "199", Address: "one13hd3zyl0jhupv6uv7lv9lcsa9ggp5l24kzdgqs", BlsPublicKey: "0d7b8e7234d46191aa27e26399c4ffb515b31d8d828f8647fca43019d02a64ad857761504454e326938192a2c65dd311"}, + {Index: "200", Address: "one1kua9tettjz0rpmp3977rhgrslw4gvm6mxw2ttl", BlsPublicKey: "91bb550fc173ecfd7af89bf292446f17cb2984c1c6f24e058ef5f9729a6a135f539489e8a068a7b1d9aa2525d87cb080"}, + {Index: "201", Address: "one1fgsn4xrhtq4ljfd394gesj4aj6pkkf0lsytmnn", BlsPublicKey: "11e163fab1c890a81d224dc9d462d56b0cef5cd1645d2edd848067ff34f480b02ac8c920c4646618f235a7e3f9bdc505"}, + {Index: "202", Address: "one1g6l7xj9w8z3uxjud8da69twzvyccqam6k5xymd", BlsPublicKey: "a11451a324fffc50f33e934bcee1bd673b7e285c24817285cea8207212aad9951aa9b6c40a5b78a7fea7ed047c48d188"}, + {Index: "203", Address: "one1l476nnnhekrnnk5m78k8jr9uxvh6y4ql7xq9fq", BlsPublicKey: "4fd4f3a680528b60f6de7d944febe5426485f0ca0816a7c44fe3355bef2f48519f75235f42732678b2a5fab860e67304"}, + {Index: "204", Address: "one1hyqkrvkad8kpttpglrl42rcthd6h0uqg2etgf4", BlsPublicKey: "1bc81f9fd333524032c5a8fbbd976b00ba8d5e0e2efe60fd8336abbaec1b5744ecef07b242efddf09bd42dbcbd2f5795"}, + {Index: "205", Address: "one1g6l7xj9w8z3uxjud8da69twzvyccqam6k5xymd", BlsPublicKey: "a11451a324fffc50f33e934bcee1bd673b7e285c24817285cea8207212aad9951aa9b6c40a5b78a7fea7ed047c48d188"}, + {Index: "206", Address: "one1kgu8jl9vtff4yklvxspg4whjwdvkqsx50zwy6g", BlsPublicKey: "94c13845fa5fb93967e1f4485255993e42cddc6cef75bd5709af76275fd9a6d6fc4e062a9f4d2b776348794fc25a2408"}, + {Index: "207", Address: "one1zr57fc7txdwvcwd6w2rn4yg6tdy0j0tjhvyj8f", BlsPublicKey: "76ac6c7d29e5e47874619816d6a441645adb0138bd02aa71d5b654cfeb9bdc1d4dd66d4e493100d48aeb558824d63408"}, } diff --git a/node/node_metrics.go b/node/node_metrics.go index f90c3a0bf..b1e80a5d7 100644 --- a/node/node_metrics.go +++ b/node/node_metrics.go @@ -4,9 +4,7 @@ import ( "math/big" "time" - "github.com/ethereum/go-ethereum/common" metrics "github.com/harmony-one/harmony/api/service/metrics" - "github.com/harmony-one/harmony/core" "github.com/rs/zerolog/log" ) @@ -19,6 +17,11 @@ func (node *Node) UpdateBlockHeightForMetrics(prevBlockHeight uint64) uint64 { } log.Info().Msgf("Updating metrics block height %d", curBlockHeight) metrics.UpdateBlockHeight(curBlockHeight) + blockReward := node.Consensus.GetBlockReward() + if blockReward != nil { + log.Info().Msgf("Updating metrics block reward %d", blockReward.Uint64()) + metrics.UpdateBlockReward(blockReward) + } return curBlockHeight } @@ -35,12 +38,7 @@ func (node *Node) UpdateConnectionsNumberForMetrics(prevNumPeers int) int { // UpdateBalanceForMetrics uppdates node balance for metrics service. func (node *Node) UpdateBalanceForMetrics(prevBalance *big.Int) *big.Int { - instance := core.ShardingSchedule.InstanceForEpoch(big.NewInt(int64(core.GetEpochFromBlockNumber(node.Blockchain().CurrentBlock().NumberU64())))) - _, account := instance.FindAccount(node.NodeConfig.ConsensusPubKey.SerializeToHexStr()) - if account == nil { - return prevBalance - } - curBalance, err := node.GetBalanceOfAddress(common.HexToAddress(account.Address)) + curBalance, err := node.GetBalanceOfAddress(node.Consensus.SelfAddress) if err != nil || curBalance.Cmp(prevBalance) == 0 { return prevBalance } @@ -67,7 +65,7 @@ func (node *Node) CollectMetrics() { prevBlockHeight := uint64(0) prevBalance := big.NewInt(0) prevLastConsensusTime := int64(0) - for range time.Tick(100 * time.Millisecond) { + for range time.Tick(1000 * time.Millisecond) { prevBlockHeight = node.UpdateBlockHeightForMetrics(prevBlockHeight) prevNumPeers = node.UpdateConnectionsNumberForMetrics(prevNumPeers) prevBalance = node.UpdateBalanceForMetrics(prevBalance)