Skip to content

Commit

Permalink
add MultiversX chain (#44)
Browse files Browse the repository at this point in the history
added MultiversX chain

implements part of #16 - MultiversX support

reworked PR #30
  • Loading branch information
raduchis committed Nov 22, 2023
1 parent 9cc7bb5 commit 4171780
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ NOTE: You can get your API Key by signing up [here](https://www.validators.app/u
18. [Sui](https://sui.io/)
19. [Pulsechain](https://pulsechain.com/)
20. [Celestia](https://celestia.org/)
21. [MultiversX](https://multiversx.com/)

### Notes

Expand Down
7 changes: 6 additions & 1 deletion core/chains/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
AVAX Token = "AVAX"
BLD Token = "BLD"
BNB Token = "BNB"
EGLD Token = "EGLD"
ETH2 Token = "ETH2"
GRT Token = "GRT"
HBAR Token = "HBAR"
Expand Down Expand Up @@ -52,6 +53,8 @@ func (t Token) ChainName() string {
return "Agoric"
case BNB:
return "Binance"
case EGLD:
return "MultiversX"
case ETH2:
return "Ethereum Proof-of-Stake"
case GRT:
Expand Down Expand Up @@ -87,7 +90,7 @@ func (t Token) ChainName() string {
}
}

var Tokens = []Token{ATOM, AVAX, BLD, BNB, ETH2, GRT, HBAR, JUNO, MATIC, MINA, NEAR, OSMO, PLS, REGEN, RUNE, SOL, STARS, SUI, TIA}
var Tokens = []Token{ATOM, AVAX, BLD, BNB, EGLD, ETH2, GRT, HBAR, JUNO, MATIC, MINA, NEAR, OSMO, PLS, REGEN, RUNE, SOL, STARS, SUI, TIA}

// NewState returns a new fresh state.
func NewState() ChainState {
Expand Down Expand Up @@ -129,6 +132,8 @@ func newValues(token Token) (int, error) {
currVal, err = Agoric()
case BNB:
currVal, err = Binance()
case EGLD:
currVal, err = MultiversX()
case ETH2:
currVal, err = Eth2()
case GRT:
Expand Down
112 changes: 112 additions & 0 deletions core/chains/multiversx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package chains

import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"sort"

"github.com/xenowits/nakamoto-coefficient-calculator/core/utils"
)

const totalValidatorsUrl = "https://api.multiversx.com/stake"
const identitiesUrl = "https://api.multiversx.com/identities"

type MultiversXTotalValidatorsResponse struct {
TotalValidators int64 `json:"totalValidators"`
}

type MultiversXIdentitiesResponse []struct {
Locked string `json:"locked"`
NumValidators int64 `json:"validators"`
}

func MultiversX() (int, error) {
numValidatorsPerIdentity := make([]int64, 0)

totalNumberOfValidators, err := getTotalValidatorsNumber()
if err != nil {
return 0, err
}

identities, err := getIdentities()
if err != nil {
return 0, err
}

for _, identity := range identities {
if identity.Locked == "0" {
continue
}
numValidatorsPerIdentity = append(numValidatorsPerIdentity, identity.NumValidators)
}

sort.Slice(numValidatorsPerIdentity, func(i, j int) bool {
return numValidatorsPerIdentity[i] > numValidatorsPerIdentity[j]
})

fmt.Println("Total voting power:", totalNumberOfValidators)

// there is a fixed number of validator seats in MultiversX - currently 3200
// the Nakamoto coefficient can be computed by counting the identities (node operators)
// that control more than 33% of the total number of validators
nakamotoCoefficient := utils.CalcNakamotoCoefficient(totalNumberOfValidators, numValidatorsPerIdentity)
fmt.Println("The Nakamoto coefficient for MultiversX is", nakamotoCoefficient)

return nakamotoCoefficient, nil
}

func getTotalValidatorsNumber() (int64, error) {
resp, err := http.Get(totalValidatorsUrl)
if err != nil {
return 0, err
}

defer closeBody(resp)

body, err := io.ReadAll(resp.Body)
if err != nil {
return 0, err
}

var response MultiversXTotalValidatorsResponse
err = json.Unmarshal(body, &response)
if err != nil {
return 0, err
}

return response.TotalValidators, nil
}

func getIdentities() (MultiversXIdentitiesResponse, error) {
resp, err := http.Get(identitiesUrl)
if err != nil {
return nil, err
}

defer closeBody(resp)

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

var response MultiversXIdentitiesResponse
err = json.Unmarshal(body, &response)
if err != nil {
return nil, err
}

return response, nil
}

func closeBody(resp *http.Response) {
if resp == nil || resp.Body == nil {
return
}
if closeErr := resp.Body.Close(); closeErr != nil {
log.Printf("failed to close response body: %s", closeErr)
}
}

0 comments on commit 4171780

Please sign in to comment.