Skip to content

Commit

Permalink
feat: implement network info method
Browse files Browse the repository at this point in the history
  • Loading branch information
andskur committed Oct 4, 2021
1 parent d03db1e commit 996cce2
Show file tree
Hide file tree
Showing 23 changed files with 899 additions and 11 deletions.
6 changes: 3 additions & 3 deletions account/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
"time"

"github.com/ethereum/go-ethereum/rpc"
"github.com/gateway-fm/near-api-go/config"
itypes "github.com/gateway-fm/near-api-go/internal/types"
"github.com/gateway-fm/near-api-go/keys"
"github.com/gateway-fm/near-api-go/transaction"
"github.com/gateway-fm/near-api-go/types"
"github.com/gateway-fm/near-api-go/util"
"github.com/mr-tron/base58/base58"
"github.com/near/borsh-go"
Expand All @@ -31,12 +31,12 @@ var (

// Account provides functions for a single account.
type Account struct {
config *types.Config
config *config.Config
accountID string
}

// NewAccount creates a new account.
func NewAccount(config *types.Config, accountID string) *Account {
func NewAccount(config *config.Config, accountID string) *Account {
return &Account{
config: config,
accountID: accountID,
Expand Down
4 changes: 2 additions & 2 deletions account/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"context"

"github.com/ethereum/go-ethereum/rpc"
"github.com/gateway-fm/near-api-go/config"
"github.com/gateway-fm/near-api-go/keys"
"github.com/gateway-fm/near-api-go/types"
"github.com/stretchr/testify/require"

"testing"
Expand Down Expand Up @@ -96,7 +96,7 @@ func makeAccount(t *testing.T) (*Account, func()) {
// )
// require.NoError(t, err)

config := &types.Config{
config := &config.Config{
RPCClient: rpcClient,
NetworkID: "testnet",
// Signer: keys,
Expand Down
18 changes: 15 additions & 3 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/gateway-fm/near-api-go/models"

"github.com/ethereum/go-ethereum/rpc"

"github.com/gateway-fm/near-api-go/account"
"github.com/gateway-fm/near-api-go/config"
itypes "github.com/gateway-fm/near-api-go/internal/types"
"github.com/gateway-fm/near-api-go/types"
"github.com/gateway-fm/near-api-go/util"
)

Expand Down Expand Up @@ -120,11 +122,11 @@ type NodeStatusResponse struct {

// Client communicates with the NEAR API.
type Client struct {
config *types.Config
config *config.Config
}

// NewClient creates a new Client.
func NewClient(config *types.Config) (*Client, error) {
func NewClient(config *config.Config) (*Client, error) {
return &Client{
config: config,
}, nil
Expand Down Expand Up @@ -332,3 +334,13 @@ func (c *Client) NodeStatus(ctx context.Context) (*NodeStatusResponse, error) {
}
return &nodeStatusRes, nil
}

// NetworkInfo returns the current state of node network
// connections (active peers, transmitted data, etc.)
func (c *Client) NetworkInfo(ctx context.Context) (*models.NetworkInfo, error) {
var networkInfo models.NetworkInfo
if err := c.config.RPCClient.CallContext(ctx, &networkInfo, "network_info"); err != nil {
return nil, fmt.Errorf("calling network info rpc: %v", util.MapRPCError(err))
}
return &networkInfo, nil
}
4 changes: 2 additions & 2 deletions api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"

"github.com/ethereum/go-ethereum/rpc"
"github.com/gateway-fm/near-api-go/types"
"github.com/gateway-fm/near-api-go/config"
"github.com/stretchr/testify/require"

"testing"
Expand Down Expand Up @@ -65,7 +65,7 @@ func makeClient(t *testing.T) (*Client, func()) {
// )
// require.NoError(t, err)

config := &types.Config{
config := &config.Config{
RPCClient: rpcClient,
// Signer: keys,
NetworkID: "testnet",
Expand Down
2 changes: 1 addition & 1 deletion types/types.go → config/config.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package types
package config

import (
"github.com/ethereum/go-ethereum/rpc"
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ go 1.16

require (
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/eteu-technologies/near-api-go v0.0.1
github.com/ethereum/go-ethereum v1.10.9
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/google/gofuzz v1.2.0
github.com/mr-tron/base58 v1.2.0
github.com/near/borsh-go v0.3.0
github.com/stretchr/testify v1.7.0
Expand All @@ -17,6 +19,7 @@ require (
golang.org/x/tools v0.1.4 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
lukechampine.com/uint128 v1.1.1
)

replace github.com/ethereum/go-ethereum => github.com/textileio/go-ethereum v1.10.3-0.20210413172519-62e8b38d82b1
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7j
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/eteu-technologies/borsh-go v0.3.2/go.mod h1:WK4tVIecqMGB9WXrvULSeEe3POIXw+ZUFWV4HRTUCZA=
github.com/eteu-technologies/golang-uint128 v1.1.1-eteu/go.mod h1:5Vr5yDsJV9eBl44ziSgt1xDZbVfJv4+IpqnUf0wa8t4=
github.com/eteu-technologies/golang-uint128 v1.1.2-eteu h1:hEc9sN76qbV0l40GUq2lMyBDXZlTkts7cLCd+3vHkao=
github.com/eteu-technologies/golang-uint128 v1.1.2-eteu/go.mod h1:5Vr5yDsJV9eBl44ziSgt1xDZbVfJv4+IpqnUf0wa8t4=
github.com/eteu-technologies/near-api-go v0.0.1 h1:nYinLfSNIPYgxCQLOgug1eOYMq99xmn/dTriqXVmlco=
github.com/eteu-technologies/near-api-go v0.0.1/go.mod h1:yNWEYxhMGw0rIAaJfNnDsOG3dHs/y85RDiUGKVGy+oc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
Expand Down Expand Up @@ -154,6 +160,8 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
Expand Down Expand Up @@ -615,5 +623,7 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
121 changes: 121 additions & 0 deletions models/network_structs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package models

import (
"encoding/json"
"time"

"github.com/gateway-fm/near-api-go/types"
"github.com/gateway-fm/near-api-go/types/hash"
"github.com/gateway-fm/near-api-go/types/key"
"github.com/gateway-fm/near-api-go/types/signature"
)

// NetworkInfo holds network information
type NetworkInfo struct {
ActivePeers []FullPeerInfo `json:"active_peers"`
NumActivePeers uint `json:"num_active_peers"`
PeerMaxCount uint32 `json:"peer_max_count"`
HighestHeightPeers []FullPeerInfo `json:"highest_height_peers"`
SentBytesPerSec uint64 `json:"sent_bytes_per_sec"`
ReceivedBytesPerSec uint64 `json:"received_bytes_per_sec"`
KnownProducers []KnownProducer `json:"known_producers"`
MetricRecorder MetricRecorder `json:"metric_recorder"`
PeerCounter uint `json:"peer_counter"`
}

type FullPeerInfo struct {
PeerInfo PeerInfo `json:"peer_info"`
ChainInfo PeerChainInfo `json:"chain_info"`
EdgeInfo EdgeInfo `json:"edge_info"`
}

// PeerInfo holds peer information
type PeerInfo struct {
ID key.PeerID `json:"id"`
Addr *string `json:"addr"`
AccountID *types.AccountID `json:"account_id"`
}

// PeerChainInfo contains peer chain information. This is derived from PeerCHainInfoV2 in nearcore
type PeerChainInfo struct {
// Chain Id and hash of genesis block.
GenesisID GenesisID `json:"genesis_id"`
// Last known chain height of the peer.
Height types.BlockHeight `json:"height"`
// Shards that the peer is tracking.
TrackedShards []types.ShardID `json:"tracked_shards"`
// Denote if a node is running in archival mode or not.
Archival bool `json:"archival"`
}

// EdgeInfo contains information that will be ultimately used to create a new edge. It contains nonce proposed for the edge with signature from peer.
type EdgeInfo struct {
Nonce types.Nonce `json:"nonce"`
Signature signature.Signature `json:"signature"`
}

// KnownProducer is basically PeerInfo, but AccountID is known
type KnownProducer struct {
AccountID types.AccountID `json:"account_id"`
Addr *string `json:"addr"`
PeerID key.PeerID `json:"peer_id"`
}

// TODO: chain/network/src/recorder.rs
type MetricRecorder = json.RawMessage

type GenesisID struct {
// Chain Id
ChainID string `json:"chain_id"`
// Hash of genesis block
Hash hash.CryptoHash `json:"hash"`
}

type StatusResponse struct {
// Binary version
Version NodeVersion `json:"version"`
// Unique chain id.
ChainID string `json:"chain_id"`
// Currently active protocol version.
ProtocolVersion uint32 `json:"protocol_version"`
// Latest protocol version that this client supports.
LatestProtocolVersion uint32 `json:"latest_protocol_version"`
// Address for RPC server.
RPCAddr string `json:"rpc_addr"`
// Current epoch validators.
Validators []ValidatorInfo `json:"validators"`
// Sync status of the node.
SyncInfo StatusSyncInfo `json:"sync_info"`
// Validator id of the node
ValidatorAccountID *types.AccountID `json:"validator_account_id"`
}

type NodeVersion struct {
Version string `json:"version"`
Build string `json:"build"`
}

type ValidatorInfo struct {
AccountID types.AccountID `json:"account_id"`
Slashed bool `json:"is_slashed"`
}

type StatusSyncInfo struct {
LatestBlockHash hash.CryptoHash `json:"latest_block_hash"`
LatestBlockHeight types.BlockHeight `json:"latest_block_height"`
LatestBlockTime time.Time `json:"latest_block_time"`
Syncing bool `json:"syncing"`
}

type ValidatorsResponse struct {
CurrentValidators []CurrentEpochValidatorInfo `json:"current_validator"`
}

type CurrentEpochValidatorInfo struct {
ValidatorInfo
PublicKey key.PublicKey `json:"public_key"`
Stake types.Balance `json:"stake"`
Shards []types.ShardID `json:"shards"`
NumProducedBlocks types.NumBlocks `json:"num_produced_blocks"`
NumExpectedBlocks types.NumBlocks `json:"num_expected_blocks"`
}
98 changes: 98 additions & 0 deletions types/balance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package types

import (
"encoding/json"
"fmt"
"math"
"math/big"

uint128 "lukechampine.com/uint128"
)

var (
tenPower24 = uint128.From64(uint64(math.Pow10(12))).Mul64(uint64(math.Pow10(12)))
zeroNEAR = Balance(uint128.From64(0))
)

// Balance holds amount of yoctoNEAR
type Balance uint128.Uint128

func (bal *Balance) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}

val := big.Int{}
if _, ok := val.SetString(s, 10); !ok {
return fmt.Errorf("unable to parse '%s'", s)
}

*bal = Balance(uint128.FromBig(&val))

return nil
}

func (bal Balance) MarshalJSON() ([]byte, error) {
return json.Marshal(bal.String())
}

func (bal Balance) String() string {
return uint128.Uint128(bal).String()
}

// Convenience funcs
func (bal Balance) Div64(div uint64) Balance {
return Balance(uint128.Uint128(bal).Div64(div))
}

// TODO
func NEARToYocto(near uint64) Balance {
if near == 0 {
return zeroNEAR
}

return Balance(uint128.From64(near).Mul(tenPower24))
}

// TODO
func YoctoToNEAR(yocto Balance) uint64 {
div := uint128.Uint128(yocto).Div(tenPower24)
if h := div.Hi; h != 0 {
panic(fmt.Errorf("yocto div failed, remaining: %d", h))
}

return div.Lo
}

func scaleToYocto(f *big.Float) (r *big.Int) {
// Convert reference 1 NEAR to big.Float
base := new(big.Float).SetPrec(128).SetInt(uint128.Uint128(NEARToYocto(1)).Big())

// Multiply base using the supplied float
// XXX: small precision issues here will haunt me forever
bigf2 := new(big.Float).SetPrec(128).SetMode(big.ToZero).Mul(base, f)

// Convert it to big.Int
r, _ = bigf2.Int(nil)
return
}

// TODO
func BalanceFromFloat(f float64) (bal Balance) {
bigf := big.NewFloat(f)
bal = Balance(uint128.FromBig(scaleToYocto(bigf)))
return
}

// TODO
func BalanceFromString(s string) (bal Balance, err error) {
var bigf *big.Float
bigf, _, err = big.ParseFloat(s, 10, 128, big.ToZero)
if err != nil {
return
}

bal = Balance(uint128.FromBig(scaleToYocto(bigf)))
return
}
Loading

0 comments on commit 996cce2

Please sign in to comment.