Merge remote-tracking branch 'harmony/main' into traceDB

pull/3799/head
peekpi 3 years ago
commit cc8bf7c9d6
  1. 68
      api/service/explorer/service.go
  2. 4
      cmd/harmony/flags.go
  3. 2
      cmd/harmony/flags_test.go
  4. 93
      internal/chain/supply.go
  5. 5
      rpc/blockchain.go

@ -5,7 +5,6 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/big"
"net" "net"
"net/http" "net/http"
"path" "path"
@ -22,7 +21,6 @@ import (
"github.com/harmony-one/harmony/hmy" "github.com/harmony-one/harmony/hmy"
"github.com/harmony-one/harmony/hmy/tracers" "github.com/harmony-one/harmony/hmy/tracers"
"github.com/harmony-one/harmony/internal/chain" "github.com/harmony-one/harmony/internal/chain"
"github.com/harmony-one/harmony/internal/common"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
@ -212,14 +210,6 @@ func (s *Service) IsAvailable() bool {
return s.storage.available.IsSet() return s.storage.available.IsSet()
} }
var (
// InaccessibleAddresses are a list of known eth addresses that cannot spend ONE tokens.
InaccessibleAddresses = []ethCommon.Address{
// one10000000000000000000000000000dead5shlag
ethCommon.HexToAddress("0x7bDeF7Bdef7BDeF7BDEf7bDef7bdef7bdeF6E7AD"),
}
)
// InaccessibleAddressInfo .. // InaccessibleAddressInfo ..
type InaccessibleAddressInfo struct { type InaccessibleAddressInfo struct {
EthAddress ethCommon.Address `json:"eth-address"` EthAddress ethCommon.Address `json:"eth-address"`
@ -228,48 +218,23 @@ type InaccessibleAddressInfo struct {
Nonce uint64 `json:"nonce"` Nonce uint64 `json:"nonce"`
} }
// getAllInaccessibleAddresses information according to InaccessibleAddresses
func (s *Service) getAllInaccessibleAddresses() ([]*InaccessibleAddressInfo, error) {
state, err := s.blockchain.StateAt(s.blockchain.CurrentHeader().Root())
if err != nil {
return nil, err
}
accs := []*InaccessibleAddressInfo{}
for _, addr := range InaccessibleAddresses {
accs = append(accs, &InaccessibleAddressInfo{
EthAddress: addr,
Address: common.MustAddressToBech32(addr),
Balance: numeric.NewDecFromBigIntWithPrec(state.GetBalance(addr), 18),
Nonce: state.GetNonce(addr),
})
}
return accs, nil
}
// getTotalInaccessibleTokens in ONE at the latest header.
func (s *Service) getTotalInaccessibleTokens() (numeric.Dec, error) {
addrInfos, err := s.getAllInaccessibleAddresses()
if err != nil {
return numeric.Dec{}, err
}
total := numeric.NewDecFromBigIntWithPrec(big.NewInt(0), 18)
for _, addr := range addrInfos {
total = total.Add(addr.Balance)
}
return total, nil
}
// GetInaccessibleAddressInfo serves /burn-addresses end-point. // GetInaccessibleAddressInfo serves /burn-addresses end-point.
func (s *Service) GetInaccessibleAddressInfo(w http.ResponseWriter, r *http.Request) { func (s *Service) GetInaccessibleAddressInfo(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
accInfos, err := s.getAllInaccessibleAddresses() accInfos, err := chain.GetInaccessibleAddressInfo(s.blockchain)
if err != nil { if err != nil {
utils.Logger().Warn().Err(err).Msg("unable to fetch inaccessible addresses") utils.Logger().Warn().Err(err).Msg("unable to fetch inaccessible addresses")
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
} }
display := make([]*InaccessibleAddressInfo, 0, len(accInfos))
for _, acc := range accInfos {
display = append(display, &InaccessibleAddressInfo{
EthAddress: acc.EthAddress,
Address: acc.Address,
Balance: acc.Balance,
Nonce: acc.Nonce,
})
}
if err := json.NewEncoder(w).Encode(accInfos); err != nil { if err := json.NewEncoder(w).Encode(accInfos); err != nil {
utils.Logger().Warn().Msg("cannot JSON-encode inaccessible account info") utils.Logger().Warn().Msg("cannot JSON-encode inaccessible account info")
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
@ -280,17 +245,12 @@ func (s *Service) GetInaccessibleAddressInfo(w http.ResponseWriter, r *http.Requ
// Note that known InaccessibleAddresses have their funds removed from the supply for this endpoint. // Note that known InaccessibleAddresses have their funds removed from the supply for this endpoint.
func (s *Service) GetCirculatingSupply(w http.ResponseWriter, r *http.Request) { func (s *Service) GetCirculatingSupply(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
circulatingSupply, err := chain.GetCirculatingSupply(context.Background(), s.blockchain) cs, err := chain.GetCirculatingSupply(s.blockchain)
if err != nil { if err != nil {
utils.Logger().Warn().Err(err).Msg("unable to fetch circulating supply") utils.Logger().Warn().Msg("Failed to get circulating supply")
w.WriteHeader(http.StatusInternalServerError)
}
totalInaccessible, err := s.getTotalInaccessibleTokens()
if err != nil {
utils.Logger().Warn().Err(err).Msg("unable to fetch inaccessible tokens")
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
} }
if err := json.NewEncoder(w).Encode(circulatingSupply.Sub(totalInaccessible)); err != nil { if err := json.NewEncoder(w).Encode(cs); err != nil {
utils.Logger().Warn().Msg("cannot JSON-encode circulating supply") utils.Logger().Warn().Msg("cannot JSON-encode circulating supply")
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
} }
@ -305,7 +265,7 @@ func (s *Service) GetTotalSupply(w http.ResponseWriter, r *http.Request) {
utils.Logger().Warn().Err(err).Msg("unable to fetch total supply") utils.Logger().Warn().Err(err).Msg("unable to fetch total supply")
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
} }
totalInaccessible, err := s.getTotalInaccessibleTokens() totalInaccessible, err := chain.GetInaccessibleTokens(s.blockchain)
if err != nil { if err != nil {
utils.Logger().Warn().Err(err).Msg("unable to fetch inaccessible tokens") utils.Logger().Warn().Err(err).Msg("unable to fetch inaccessible tokens")
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)

@ -320,10 +320,6 @@ func applyGeneralFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig)
config.General.NodeType = cli.GetStringFlagValue(cmd, legacyNodeTypeFlag) config.General.NodeType = cli.GetStringFlagValue(cmd, legacyNodeTypeFlag)
} }
if config.General.NodeType == nodeTypeExplorer {
config.General.IsArchival = true
}
if cli.IsFlagChanged(cmd, shardIDFlag) { if cli.IsFlagChanged(cmd, shardIDFlag) {
config.General.ShardID = cli.GetIntFlagValue(cmd, shardIDFlag) config.General.ShardID = cli.GetIntFlagValue(cmd, shardIDFlag)
} else if cli.IsFlagChanged(cmd, legacyShardIDFlag) { } else if cli.IsFlagChanged(cmd, legacyShardIDFlag) {

@ -198,7 +198,7 @@ func TestGeneralFlags(t *testing.T) {
NodeType: "explorer", NodeType: "explorer",
NoStaking: false, NoStaking: false,
ShardID: 0, ShardID: 0,
IsArchival: true, IsArchival: false,
DataDir: "./", DataDir: "./",
}, },
}, },

@ -1,29 +1,75 @@
package chain package chain
import ( import (
"context"
"math/big" "math/big"
"time" "time"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/consensus/reward" "github.com/harmony-one/harmony/consensus/reward"
common2 "github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
stakingReward "github.com/harmony-one/harmony/staking/reward" stakingReward "github.com/harmony-one/harmony/staking/reward"
"github.com/pkg/errors"
) )
// GetCirculatingSupply using the following formula: // Circulating supply calculation
var (
// InaccessibleAddresses are a list of known eth addresses that cannot spend ONE tokens.
InaccessibleAddresses = []common.Address{
// one10000000000000000000000000000dead5shlag
common.HexToAddress("0x7bDeF7Bdef7BDeF7BDEf7bDef7bdef7bdeF6E7AD"),
}
)
// InaccessibleAddressInfo is the structure for inaccessible addresses
type InaccessibleAddressInfo struct {
EthAddress common.Address
Address string // One address
Balance numeric.Dec
Nonce uint64
}
// GetCirculatingSupply get the circulating supply.
// The value is the total circulating supply sub the tokens burnt at
// inaccessible addresses.
// WARNING: only works on beacon chain if in staking era.
func GetCirculatingSupply(chain engine.ChainReader) (numeric.Dec, error) {
total, err := getTotalCirculatingSupply(chain)
if err != nil {
return numeric.Dec{}, err
}
invalid, err := getAllInaccessibleTokens(chain)
if err != nil {
return numeric.Dec{}, err
}
if total.LT(invalid) {
return numeric.Dec{}, errors.New("FATAL: negative circulating supply")
}
return total.Sub(invalid), nil
}
// GetInaccessibleAddressInfo return the information of all inaccessible
// addresses.
func GetInaccessibleAddressInfo(chain engine.ChainReader) ([]*InaccessibleAddressInfo, error) {
return getAllInaccessibleAddresses(chain)
}
// GetInaccessibleTokens get the total inaccessible tokens.
// The amount is the sum of balance at all inaccessible addresses.
func GetInaccessibleTokens(chain engine.ChainReader) (numeric.Dec, error) {
return getAllInaccessibleTokens(chain)
}
// getTotalCirculatingSupply using the following formula:
// (TotalInitialTokens * percentReleased) + PreStakingBlockRewards + StakingBlockRewards // (TotalInitialTokens * percentReleased) + PreStakingBlockRewards + StakingBlockRewards
// //
// Note that PreStakingBlockRewards is set to the amount of rewards given out by the // Note that PreStakingBlockRewards is set to the amount of rewards given out by the
// LAST BLOCK of the pre-staking era regardless of what the current block height is // LAST BLOCK of the pre-staking era regardless of what the current block height is
// if network is in the pre-staking era. This is for implementation reasons, reference // if network is in the pre-staking era. This is for implementation reasons, reference
// stakingReward.GetTotalPreStakingTokens for more details. // stakingReward.GetTotalPreStakingTokens for more details.
// func getTotalCirculatingSupply(chain engine.ChainReader) (ret numeric.Dec, err error) {
// WARNING: only works on beaconchain if in staking era.
func GetCirculatingSupply(
ctx context.Context, chain engine.ChainReader,
) (ret numeric.Dec, err error) {
currHeader, timestamp := chain.CurrentHeader(), time.Now().Unix() currHeader, timestamp := chain.CurrentHeader(), time.Now().Unix()
stakingBlockRewards := big.NewInt(0) stakingBlockRewards := big.NewInt(0)
@ -44,3 +90,36 @@ func GetCirculatingSupply(
numeric.NewDecFromBigIntWithPrec(stakingBlockRewards, 18), numeric.NewDecFromBigIntWithPrec(stakingBlockRewards, 18),
), nil ), nil
} }
func getAllInaccessibleTokens(chain engine.ChainReader) (numeric.Dec, error) {
ais, err := getAllInaccessibleAddresses(chain)
if err != nil {
return numeric.Dec{}, err
}
total := numeric.NewDecFromBigIntWithPrec(big.NewInt(0), numeric.Precision)
for _, ai := range ais {
total = total.Add(ai.Balance)
}
return total, nil
}
func getAllInaccessibleAddresses(chain engine.ChainReader) ([]*InaccessibleAddressInfo, error) {
state, err := chain.StateAt(chain.CurrentHeader().Root())
if err != nil {
return nil, err
}
accs := make([]*InaccessibleAddressInfo, 0, len(InaccessibleAddresses))
for _, addr := range InaccessibleAddresses {
nonce := state.GetNonce(addr)
oneAddr, _ := common2.AddressToBech32(addr)
balance := state.GetBalance(addr)
accs = append(accs, &InaccessibleAddressInfo{
EthAddress: addr,
Address: oneAddr,
Balance: numeric.NewDecFromBigIntWithPrec(balance, numeric.Precision),
Nonce: nonce,
})
}
return accs, nil
}

@ -7,6 +7,8 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/harmony-one/harmony/internal/chain"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -15,7 +17,6 @@ import (
"golang.org/x/time/rate" "golang.org/x/time/rate"
"github.com/harmony-one/harmony/hmy" "github.com/harmony-one/harmony/hmy"
"github.com/harmony-one/harmony/internal/chain"
internal_common "github.com/harmony-one/harmony/internal/common" internal_common "github.com/harmony-one/harmony/internal/common"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
@ -767,7 +768,7 @@ func (s *PublicBlockchainService) GetTotalSupply(
func (s *PublicBlockchainService) GetCirculatingSupply( func (s *PublicBlockchainService) GetCirculatingSupply(
ctx context.Context, ctx context.Context,
) (numeric.Dec, error) { ) (numeric.Dec, error) {
return chain.GetCirculatingSupply(ctx, s.hmy.BlockChain) return chain.GetCirculatingSupply(s.hmy.BlockChain)
} }
// GetStakingNetworkInfo .. // GetStakingNetworkInfo ..

Loading…
Cancel
Save