Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
4c8c5e2f
Commit
4c8c5e2f
authored
Nov 25, 2016
by
Péter Szilágyi
Committed by
Felix Lange
Nov 25, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd, ethstats, les, mobile, params: native netstats (#3336)
parent
d1a95c64
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
533 additions
and
46 deletions
+533
-46
consolecmd_test.go
cmd/geth/consolecmd_test.go
+3
-3
main.go
cmd/geth/main.go
+28
-7
usage.go
cmd/geth/usage.go
+1
-0
flags.go
cmd/utils/flags.go
+27
-5
ethstats.go
ethstats/ethstats.go
+452
-0
backend.go
les/backend.go
+1
-0
geth.go
mobile/geth.go
+19
-0
version.go
params/version.go
+2
-31
No files found.
cmd/geth/consolecmd_test.go
View file @
4c8c5e2f
...
@@ -28,7 +28,7 @@ import (
...
@@ -28,7 +28,7 @@ import (
"testing"
"testing"
"time"
"time"
"github.com/ethereum/go-ethereum/
cmd/util
s"
"github.com/ethereum/go-ethereum/
param
s"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/rpc"
)
)
...
@@ -46,7 +46,7 @@ func TestConsoleWelcome(t *testing.T) {
...
@@ -46,7 +46,7 @@ func TestConsoleWelcome(t *testing.T) {
// Gather all the infos the welcome message needs to contain
// Gather all the infos the welcome message needs to contain
geth
.
setTemplateFunc
(
"goos"
,
func
()
string
{
return
runtime
.
GOOS
})
geth
.
setTemplateFunc
(
"goos"
,
func
()
string
{
return
runtime
.
GOOS
})
geth
.
setTemplateFunc
(
"gover"
,
runtime
.
Version
)
geth
.
setTemplateFunc
(
"gover"
,
runtime
.
Version
)
geth
.
setTemplateFunc
(
"gethver"
,
func
()
string
{
return
util
s
.
Version
})
geth
.
setTemplateFunc
(
"gethver"
,
func
()
string
{
return
param
s
.
Version
})
geth
.
setTemplateFunc
(
"niltime"
,
func
()
string
{
return
time
.
Unix
(
0
,
0
)
.
Format
(
time
.
RFC1123
)
})
geth
.
setTemplateFunc
(
"niltime"
,
func
()
string
{
return
time
.
Unix
(
0
,
0
)
.
Format
(
time
.
RFC1123
)
})
geth
.
setTemplateFunc
(
"apis"
,
func
()
[]
string
{
geth
.
setTemplateFunc
(
"apis"
,
func
()
[]
string
{
apis
:=
append
(
strings
.
Split
(
rpc
.
DefaultIPCApis
,
","
),
rpc
.
MetadataApi
)
apis
:=
append
(
strings
.
Split
(
rpc
.
DefaultIPCApis
,
","
),
rpc
.
MetadataApi
)
...
@@ -132,7 +132,7 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint string) {
...
@@ -132,7 +132,7 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint string) {
// Gather all the infos the welcome message needs to contain
// Gather all the infos the welcome message needs to contain
attach
.
setTemplateFunc
(
"goos"
,
func
()
string
{
return
runtime
.
GOOS
})
attach
.
setTemplateFunc
(
"goos"
,
func
()
string
{
return
runtime
.
GOOS
})
attach
.
setTemplateFunc
(
"gover"
,
runtime
.
Version
)
attach
.
setTemplateFunc
(
"gover"
,
runtime
.
Version
)
attach
.
setTemplateFunc
(
"gethver"
,
func
()
string
{
return
util
s
.
Version
})
attach
.
setTemplateFunc
(
"gethver"
,
func
()
string
{
return
param
s
.
Version
})
attach
.
setTemplateFunc
(
"etherbase"
,
func
()
string
{
return
geth
.
Etherbase
})
attach
.
setTemplateFunc
(
"etherbase"
,
func
()
string
{
return
geth
.
Etherbase
})
attach
.
setTemplateFunc
(
"niltime"
,
func
()
string
{
return
time
.
Unix
(
0
,
0
)
.
Format
(
time
.
RFC1123
)
})
attach
.
setTemplateFunc
(
"niltime"
,
func
()
string
{
return
time
.
Unix
(
0
,
0
)
.
Format
(
time
.
RFC1123
)
})
attach
.
setTemplateFunc
(
"ipc"
,
func
()
bool
{
return
strings
.
HasPrefix
(
endpoint
,
"ipc"
)
})
attach
.
setTemplateFunc
(
"ipc"
,
func
()
bool
{
return
strings
.
HasPrefix
(
endpoint
,
"ipc"
)
})
...
...
cmd/geth/main.go
View file @
4c8c5e2f
...
@@ -40,6 +40,8 @@ import (
...
@@ -40,6 +40,8 @@ import (
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"gopkg.in/urfave/cli.v1"
"gopkg.in/urfave/cli.v1"
)
)
...
@@ -173,6 +175,7 @@ participating.
...
@@ -173,6 +175,7 @@ participating.
utils
.
VMEnableJitFlag
,
utils
.
VMEnableJitFlag
,
utils
.
NetworkIdFlag
,
utils
.
NetworkIdFlag
,
utils
.
RPCCORSDomainFlag
,
utils
.
RPCCORSDomainFlag
,
utils
.
EthStatsURLFlag
,
utils
.
MetricsEnabledFlag
,
utils
.
MetricsEnabledFlag
,
utils
.
FakePoWFlag
,
utils
.
FakePoWFlag
,
utils
.
SolcPathFlag
,
utils
.
SolcPathFlag
,
...
@@ -254,8 +257,24 @@ func initGenesis(ctx *cli.Context) error {
...
@@ -254,8 +257,24 @@ func initGenesis(ctx *cli.Context) error {
}
}
func
makeFullNode
(
ctx
*
cli
.
Context
)
*
node
.
Node
{
func
makeFullNode
(
ctx
*
cli
.
Context
)
*
node
.
Node
{
// Create the default extradata and construct the base node
var
clientInfo
=
struct
{
Version
uint
Name
string
GoVersion
string
Os
string
}{
uint
(
params
.
VersionMajor
<<
16
|
params
.
VersionMinor
<<
8
|
params
.
VersionPatch
),
clientIdentifier
,
runtime
.
Version
(),
runtime
.
GOOS
}
extra
,
err
:=
rlp
.
EncodeToBytes
(
clientInfo
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Warn
)
.
Infoln
(
"error setting canonical miner information:"
,
err
)
}
if
uint64
(
len
(
extra
))
>
params
.
MaximumExtraDataSize
.
Uint64
()
{
glog
.
V
(
logger
.
Warn
)
.
Infoln
(
"error setting canonical miner information: extra exceeds"
,
params
.
MaximumExtraDataSize
)
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"extra: %x
\n
"
,
extra
)
extra
=
nil
}
stack
:=
utils
.
MakeNode
(
ctx
,
clientIdentifier
,
gitCommit
)
stack
:=
utils
.
MakeNode
(
ctx
,
clientIdentifier
,
gitCommit
)
utils
.
RegisterEthService
(
ctx
,
stack
,
utils
.
MakeDefaultExtraData
(
clientIdentifier
)
)
utils
.
RegisterEthService
(
ctx
,
stack
,
extra
)
// Whisper must be explicitly enabled, but is auto-enabled in --dev mode.
// Whisper must be explicitly enabled, but is auto-enabled in --dev mode.
shhEnabled
:=
ctx
.
GlobalBool
(
utils
.
WhisperEnabledFlag
.
Name
)
shhEnabled
:=
ctx
.
GlobalBool
(
utils
.
WhisperEnabledFlag
.
Name
)
...
@@ -263,14 +282,17 @@ func makeFullNode(ctx *cli.Context) *node.Node {
...
@@ -263,14 +282,17 @@ func makeFullNode(ctx *cli.Context) *node.Node {
if
shhEnabled
||
shhAutoEnabled
{
if
shhEnabled
||
shhAutoEnabled
{
utils
.
RegisterShhService
(
stack
)
utils
.
RegisterShhService
(
stack
)
}
}
// Add the Ethereum Stats daemon if requested
if
url
:=
ctx
.
GlobalString
(
utils
.
EthStatsURLFlag
.
Name
);
url
!=
""
{
utils
.
RegisterEthStatsService
(
stack
,
url
)
}
// Add the release oracle service so it boots along with node.
// Add the release oracle service so it boots along with node.
if
err
:=
stack
.
Register
(
func
(
ctx
*
node
.
ServiceContext
)
(
node
.
Service
,
error
)
{
if
err
:=
stack
.
Register
(
func
(
ctx
*
node
.
ServiceContext
)
(
node
.
Service
,
error
)
{
config
:=
release
.
Config
{
config
:=
release
.
Config
{
Oracle
:
relOracle
,
Oracle
:
relOracle
,
Major
:
uint32
(
util
s
.
VersionMajor
),
Major
:
uint32
(
param
s
.
VersionMajor
),
Minor
:
uint32
(
util
s
.
VersionMinor
),
Minor
:
uint32
(
param
s
.
VersionMinor
),
Patch
:
uint32
(
util
s
.
VersionPatch
),
Patch
:
uint32
(
param
s
.
VersionPatch
),
}
}
commit
,
_
:=
hex
.
DecodeString
(
gitCommit
)
commit
,
_
:=
hex
.
DecodeString
(
gitCommit
)
copy
(
config
.
Commit
[
:
],
commit
)
copy
(
config
.
Commit
[
:
],
commit
)
...
@@ -278,7 +300,6 @@ func makeFullNode(ctx *cli.Context) *node.Node {
...
@@ -278,7 +300,6 @@ func makeFullNode(ctx *cli.Context) *node.Node {
});
err
!=
nil
{
});
err
!=
nil
{
utils
.
Fatalf
(
"Failed to register the Geth release oracle service: %v"
,
err
)
utils
.
Fatalf
(
"Failed to register the Geth release oracle service: %v"
,
err
)
}
}
return
stack
return
stack
}
}
...
@@ -342,7 +363,7 @@ func makedag(ctx *cli.Context) error {
...
@@ -342,7 +363,7 @@ func makedag(ctx *cli.Context) error {
func
version
(
ctx
*
cli
.
Context
)
error
{
func
version
(
ctx
*
cli
.
Context
)
error
{
fmt
.
Println
(
strings
.
Title
(
clientIdentifier
))
fmt
.
Println
(
strings
.
Title
(
clientIdentifier
))
fmt
.
Println
(
"Version:"
,
util
s
.
Version
)
fmt
.
Println
(
"Version:"
,
param
s
.
Version
)
if
gitCommit
!=
""
{
if
gitCommit
!=
""
{
fmt
.
Println
(
"Git Commit:"
,
gitCommit
)
fmt
.
Println
(
"Git Commit:"
,
gitCommit
)
}
}
...
...
cmd/geth/usage.go
View file @
4c8c5e2f
...
@@ -161,6 +161,7 @@ var AppHelpFlagGroups = []flagGroup{
...
@@ -161,6 +161,7 @@ var AppHelpFlagGroups = []flagGroup{
{
{
Name
:
"LOGGING AND DEBUGGING"
,
Name
:
"LOGGING AND DEBUGGING"
,
Flags
:
append
([]
cli
.
Flag
{
Flags
:
append
([]
cli
.
Flag
{
utils
.
EthStatsURLFlag
,
utils
.
MetricsEnabledFlag
,
utils
.
MetricsEnabledFlag
,
utils
.
FakePoWFlag
,
utils
.
FakePoWFlag
,
},
debug
.
Flags
...
),
},
debug
.
Flags
...
),
...
...
cmd/utils/flags.go
View file @
4c8c5e2f
...
@@ -14,6 +14,7 @@
...
@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
// Package utils contains internal helper functions for go-ethereum commands.
package
utils
package
utils
import
(
import
(
...
@@ -36,6 +37,7 @@ import (
...
@@ -36,6 +37,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethstats"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/les"
"github.com/ethereum/go-ethereum/les"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger"
...
@@ -86,7 +88,7 @@ func NewApp(gitCommit, usage string) *cli.App {
...
@@ -86,7 +88,7 @@ func NewApp(gitCommit, usage string) *cli.App {
app
.
Author
=
""
app
.
Author
=
""
//app.Authors = nil
//app.Authors = nil
app
.
Email
=
""
app
.
Email
=
""
app
.
Version
=
Version
app
.
Version
=
params
.
Version
if
gitCommit
!=
""
{
if
gitCommit
!=
""
{
app
.
Version
+=
"-"
+
gitCommit
[
:
8
]
app
.
Version
+=
"-"
+
gitCommit
[
:
8
]
}
}
...
@@ -242,8 +244,11 @@ var (
...
@@ -242,8 +244,11 @@ var (
Name
:
"jitvm"
,
Name
:
"jitvm"
,
Usage
:
"Enable the JIT VM"
,
Usage
:
"Enable the JIT VM"
,
}
}
// Logging and debug settings
// logging and debug settings
EthStatsURLFlag
=
cli
.
StringFlag
{
Name
:
"ethstats"
,
Usage
:
"Reporting URL of a ethstats service (nodename:secret@host:port)"
,
}
MetricsEnabledFlag
=
cli
.
BoolFlag
{
MetricsEnabledFlag
=
cli
.
BoolFlag
{
Name
:
metrics
.
MetricsEnabledFlag
,
Name
:
metrics
.
MetricsEnabledFlag
,
Usage
:
"Enable metrics collection and reporting"
,
Usage
:
"Enable metrics collection and reporting"
,
...
@@ -660,7 +665,7 @@ func MakePasswordList(ctx *cli.Context) []string {
...
@@ -660,7 +665,7 @@ func MakePasswordList(ctx *cli.Context) []string {
// MakeNode configures a node with no services from command line flags.
// MakeNode configures a node with no services from command line flags.
func
MakeNode
(
ctx
*
cli
.
Context
,
name
,
gitCommit
string
)
*
node
.
Node
{
func
MakeNode
(
ctx
*
cli
.
Context
,
name
,
gitCommit
string
)
*
node
.
Node
{
vsn
:=
Version
vsn
:=
params
.
Version
if
gitCommit
!=
""
{
if
gitCommit
!=
""
{
vsn
+=
"-"
+
gitCommit
[
:
8
]
vsn
+=
"-"
+
gitCommit
[
:
8
]
}
}
...
@@ -801,13 +806,30 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) {
...
@@ -801,13 +806,30 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) {
}
}
}
}
// RegisterShhService configures
w
hisper and adds it to the given node.
// RegisterShhService configures
W
hisper and adds it to the given node.
func
RegisterShhService
(
stack
*
node
.
Node
)
{
func
RegisterShhService
(
stack
*
node
.
Node
)
{
if
err
:=
stack
.
Register
(
func
(
*
node
.
ServiceContext
)
(
node
.
Service
,
error
)
{
return
whisper
.
New
(),
nil
});
err
!=
nil
{
if
err
:=
stack
.
Register
(
func
(
*
node
.
ServiceContext
)
(
node
.
Service
,
error
)
{
return
whisper
.
New
(),
nil
});
err
!=
nil
{
Fatalf
(
"Failed to register the Whisper service: %v"
,
err
)
Fatalf
(
"Failed to register the Whisper service: %v"
,
err
)
}
}
}
}
// RegisterEthStatsService configures the Ethereum Stats daemon and adds it to
// th egiven node.
func
RegisterEthStatsService
(
stack
*
node
.
Node
,
url
string
)
{
if
err
:=
stack
.
Register
(
func
(
ctx
*
node
.
ServiceContext
)
(
node
.
Service
,
error
)
{
// Retrieve both eth and les services
var
ethServ
*
eth
.
Ethereum
ctx
.
Service
(
&
ethServ
)
var
lesServ
*
les
.
LightEthereum
ctx
.
Service
(
&
lesServ
)
return
ethstats
.
New
(
url
,
ethServ
,
lesServ
)
});
err
!=
nil
{
Fatalf
(
"Failed to register the Ethereum Stats service: %v"
,
err
)
}
}
// SetupNetwork configures the system for either the main net or some test network.
// SetupNetwork configures the system for either the main net or some test network.
func
SetupNetwork
(
ctx
*
cli
.
Context
)
{
func
SetupNetwork
(
ctx
*
cli
.
Context
)
{
switch
{
switch
{
...
...
ethstats/ethstats.go
0 → 100644
View file @
4c8c5e2f
// Copyright 2016 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Package ethstats implements the network stats reporting service.
package
ethstats
import
(
"encoding/json"
"errors"
"fmt"
"math/big"
"regexp"
"runtime"
"strconv"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/les"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rpc"
"golang.org/x/net/websocket"
)
// Service implements an Ethereum netstats reporting daemon that pushes local
// chain statistics up to a monitoring server.
type
Service
struct
{
stack
*
node
.
Node
// Temporary workaround, remove when API finalized
server
*
p2p
.
Server
// Peer-to-peer server to retrieve networking infos
eth
*
eth
.
Ethereum
// Full Ethereum service if monitoring a full node
les
*
les
.
LightEthereum
// Light Ethereum service if monitoring a light node
node
string
// Name of the node to display on the monitoring page
pass
string
// Password to authorize access to the monitoring page
host
string
// Remote address of the monitoring service
}
// New returns a monitoring service ready for stats reporting.
func
New
(
url
string
,
ethServ
*
eth
.
Ethereum
,
lesServ
*
les
.
LightEthereum
)
(
*
Service
,
error
)
{
// Parse the netstats connection url
re
:=
regexp
.
MustCompile
(
"([^:@]*)(:([^@]*))?@(.+)"
)
parts
:=
re
.
FindStringSubmatch
(
url
)
if
len
(
parts
)
!=
5
{
return
nil
,
fmt
.
Errorf
(
"invalid netstats url:
\"
%s
\"
, should be nodename:secret@host:port"
,
url
)
}
// Assemble and return the stats service
return
&
Service
{
eth
:
ethServ
,
les
:
lesServ
,
node
:
parts
[
1
],
pass
:
parts
[
3
],
host
:
parts
[
4
],
},
nil
}
// Protocols implements node.Service, returning the P2P network protocols used
// by the stats service (nil as it doesn't use the devp2p overlay network).
func
(
s
*
Service
)
Protocols
()
[]
p2p
.
Protocol
{
return
nil
}
// APIs implements node.Service, returning the RPC API endpoints provided by the
// stats service (nil as it doesn't provide any user callable APIs).
func
(
s
*
Service
)
APIs
()
[]
rpc
.
API
{
return
nil
}
// Start implements node.Service, starting up the monitoring and reporting daemon.
func
(
s
*
Service
)
Start
(
server
*
p2p
.
Server
)
error
{
s
.
server
=
server
go
s
.
loop
()
glog
.
V
(
logger
.
Info
)
.
Infoln
(
"Stats daemon started"
)
return
nil
}
// Stop implements node.Service, terminating the monitoring and reporting daemon.
func
(
s
*
Service
)
Stop
()
error
{
glog
.
V
(
logger
.
Info
)
.
Infoln
(
"Stats daemon stopped"
)
return
nil
}
// loop keeps trying to connect to the netstats server, reporting chain events
// until termination.
func
(
s
*
Service
)
loop
()
{
// Subscribe tso chain events to execute updates on
var
emux
*
event
.
TypeMux
if
s
.
eth
!=
nil
{
emux
=
s
.
eth
.
EventMux
()
}
else
{
emux
=
s
.
les
.
EventMux
()
}
headSub
:=
emux
.
Subscribe
(
core
.
ChainHeadEvent
{})
defer
headSub
.
Unsubscribe
()
txSub
:=
emux
.
Subscribe
(
core
.
TxPreEvent
{})
defer
txSub
.
Unsubscribe
()
// Loop reporting until termination
for
{
// Establish a websocket connection to the server and authenticate the node
conn
,
err
:=
websocket
.
Dial
(
fmt
.
Sprintf
(
"wss://%s/api"
,
s
.
host
),
""
,
"http://localhost/"
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Warn
)
.
Infof
(
"Stats server unreachable: %v"
,
err
)
time
.
Sleep
(
10
*
time
.
Second
)
continue
}
in
:=
json
.
NewDecoder
(
conn
)
out
:=
json
.
NewEncoder
(
conn
)
if
err
=
s
.
login
(
in
,
out
);
err
!=
nil
{
glog
.
V
(
logger
.
Warn
)
.
Infof
(
"Stats login failed: %v"
,
err
)
conn
.
Close
()
time
.
Sleep
(
10
*
time
.
Second
)
continue
}
if
err
=
s
.
report
(
in
,
out
);
err
!=
nil
{
glog
.
V
(
logger
.
Warn
)
.
Infof
(
"Initial stats report failed: %v"
,
err
)
conn
.
Close
()
continue
}
// Keep sending status updates until the connection breaks
fullReport
:=
time
.
NewTicker
(
15
*
time
.
Second
)
for
err
==
nil
{
select
{
case
<-
fullReport
.
C
:
if
err
=
s
.
report
(
in
,
out
);
err
!=
nil
{
glog
.
V
(
logger
.
Warn
)
.
Infof
(
"Full stats report failed: %v"
,
err
)
}
case
<-
headSub
.
Chan
()
:
// Exhaust events to avoid reporting too frequently
for
exhausted
:=
false
;
!
exhausted
;
{
select
{
case
<-
headSub
.
Chan
()
:
default
:
exhausted
=
true
}
}
if
err
=
s
.
reportBlock
(
out
);
err
!=
nil
{
glog
.
V
(
logger
.
Warn
)
.
Infof
(
"Block stats report failed: %v"
,
err
)
}
case
<-
txSub
.
Chan
()
:
// Exhaust events to avoid reporting too frequently
for
exhausted
:=
false
;
!
exhausted
;
{
select
{
case
<-
headSub
.
Chan
()
:
default
:
exhausted
=
true
}
}
if
err
=
s
.
reportPending
(
out
);
err
!=
nil
{
glog
.
V
(
logger
.
Warn
)
.
Infof
(
"Transaction stats report failed: %v"
,
err
)
}
}
}
// Make sure the connection is closed
conn
.
Close
()
}
}
// nodeInfo is the collection of metainformation about a node that is displayed
// on the monitoring page.
type
nodeInfo
struct
{
Name
string
`json:"name"`
Node
string
`json:"node"`
Port
int
`json:"port"`
Network
string
`json:"net"`
Protocol
string
`json:"protocol"`
API
string
`json:"api"`
Os
string
`json:"os"`
OsVer
string
`json:"os_v"`
Client
string
`json:"client"`
}
// authMsg is the authentication infos needed to login to a monitoring server.
type
authMsg
struct
{
Id
string
`json:"id"`
Info
nodeInfo
`json:"info"`
Secret
string
`json:"secret"`
}
// login tries to authorize the client at the remote server.
func
(
s
*
Service
)
login
(
in
*
json
.
Decoder
,
out
*
json
.
Encoder
)
error
{
// Construct and send the login authentication
infos
:=
s
.
server
.
NodeInfo
()
var
network
,
protocol
string
if
info
:=
infos
.
Protocols
[
"eth"
];
info
!=
nil
{
network
=
strconv
.
Itoa
(
info
.
(
*
eth
.
EthNodeInfo
)
.
Network
)
protocol
=
fmt
.
Sprintf
(
"eth/%d"
,
eth
.
ProtocolVersions
[
0
])
}
else
{
network
=
strconv
.
Itoa
(
infos
.
Protocols
[
"les"
]
.
(
*
eth
.
EthNodeInfo
)
.
Network
)
protocol
=
fmt
.
Sprintf
(
"les/%d"
,
les
.
ProtocolVersions
[
0
])
}
auth
:=
&
authMsg
{
Id
:
s
.
node
,
Info
:
nodeInfo
{
Name
:
s
.
node
,
Node
:
infos
.
Name
,
Port
:
infos
.
Ports
.
Listener
,
Network
:
network
,
Protocol
:
protocol
,
API
:
"No"
,
Os
:
runtime
.
GOOS
,
OsVer
:
runtime
.
GOARCH
,
Client
:
"0.1.1"
,
},
Secret
:
s
.
pass
,
}
login
:=
map
[
string
][]
interface
{}{
"emit"
:
[]
interface
{}{
"hello"
,
auth
},
}
if
err
:=
out
.
Encode
(
login
);
err
!=
nil
{
return
err
}
// Retrieve the remote ack or connection termination
var
ack
map
[
string
][]
string
if
err
:=
in
.
Decode
(
&
ack
);
err
!=
nil
||
len
(
ack
[
"emit"
])
!=
1
||
ack
[
"emit"
][
0
]
!=
"ready"
{
return
errors
.
New
(
"unauthorized"
)
}
return
nil
}
// report collects all possible data to report and send it to the stats server.
// This should only be used on reconnects or rarely to avoid overloading the
// server. Use the individual methods for reporting subscribed events.
func
(
s
*
Service
)
report
(
in
*
json
.
Decoder
,
out
*
json
.
Encoder
)
error
{
if
err
:=
s
.
reportLatency
(
in
,
out
);
err
!=
nil
{
return
err
}
if
err
:=
s
.
reportBlock
(
out
);
err
!=
nil
{
return
err
}
if
err
:=
s
.
reportPending
(
out
);
err
!=
nil
{
return
err
}
if
err
:=
s
.
reportStats
(
out
);
err
!=
nil
{
return
err
}
return
nil
}
// reportLatency sends a ping request to the server, measures the RTT time and
// finally sends a latency update.
func
(
s
*
Service
)
reportLatency
(
in
*
json
.
Decoder
,
out
*
json
.
Encoder
)
error
{
// Send the current time to the ethstats server
start
:=
time
.
Now
()
ping
:=
map
[
string
][]
interface
{}{
"emit"
:
[]
interface
{}{
"node-ping"
,
map
[
string
]
string
{
"id"
:
s
.
node
,
"clientTime"
:
start
.
String
(),
}},
}
if
err
:=
out
.
Encode
(
ping
);
err
!=
nil
{
return
err
}
// Wait for the pong request to arrive back
var
pong
map
[
string
][]
interface
{}
if
err
:=
in
.
Decode
(
&
pong
);
err
!=
nil
||
len
(
pong
[
"emit"
])
!=
2
||
pong
[
"emit"
][
0
]
.
(
string
)
!=
"node-pong"
{
return
errors
.
New
(
"unexpected ping reply"
)
}
// Send back the measured latency
latency
:=
map
[
string
][]
interface
{}{
"emit"
:
[]
interface
{}{
"latency"
,
map
[
string
]
string
{
"id"
:
s
.
node
,
"latency"
:
strconv
.
Itoa
(
int
((
time
.
Since
(
start
)
/
time
.
Duration
(
2
))
.
Nanoseconds
()
/
1000000
)),
}},
}
if
err
:=
out
.
Encode
(
latency
);
err
!=
nil
{
return
err
}
return
nil
}
// blockStats is the information to report about individual blocks.
type
blockStats
struct
{
Number
*
big
.
Int
`json:"number"`
Hash
common
.
Hash
`json:"hash"`
Diff
string
`json:"difficulty"`
TotalDiff
string
`json:"totalDifficulty"`
Txs
txStats
`json:"transactions"`
Uncles
uncleStats
`json:"uncles"`
}
// txStats is a custom wrapper around a transaction array to force serializing
// empty arrays instead of returning null for them.
type
txStats
[]
*
types
.
Transaction
func
(
s
txStats
)
MarshalJSON
()
([]
byte
,
error
)
{
if
txs
:=
([]
*
types
.
Transaction
)(
s
);
len
(
txs
)
>
0
{
return
json
.
Marshal
(
txs
)
}
return
[]
byte
(
"[]"
),
nil
}
// uncleStats is a custom wrapper around an uncle array to force serializing
// empty arrays instead of returning null for them.
type
uncleStats
[]
*
types
.
Header
func
(
s
uncleStats
)
MarshalJSON
()
([]
byte
,
error
)
{
if
uncles
:=
([]
*
types
.
Header
)(
s
);
len
(
uncles
)
>
0
{
return
json
.
Marshal
(
uncles
)
}
return
[]
byte
(
"[]"
),
nil
}
// reportBlock retrieves the current chain head and repors it to the stats server.
func
(
s
*
Service
)
reportBlock
(
out
*
json
.
Encoder
)
error
{
// Gather the head block infos from the local blockchain
var
(
head
*
types
.
Header
td
*
big
.
Int
txs
[]
*
types
.
Transaction
uncles
[]
*
types
.
Header
)
if
s
.
eth
!=
nil
{
// Full nodes have all needed information available
block
:=
s
.
eth
.
BlockChain
()
.
CurrentBlock
()
head
=
s
.
eth
.
BlockChain
()
.
CurrentHeader
()
td
=
s
.
eth
.
BlockChain
()
.
GetTd
(
head
.
Hash
(),
head
.
Number
.
Uint64
())
txs
=
block
.
Transactions
()
uncles
=
block
.
Uncles
()
}
else
{
// Light nodes would need on-demand lookups for transactions/uncles, skip
head
=
s
.
les
.
BlockChain
()
.
CurrentHeader
()
td
=
s
.
les
.
BlockChain
()
.
GetTd
(
head
.
Hash
(),
head
.
Number
.
Uint64
())
}
// Assemble the block stats report and send it to the server
stats
:=
map
[
string
]
interface
{}{
"id"
:
s
.
node
,
"block"
:
&
blockStats
{
Number
:
head
.
Number
,
Hash
:
head
.
Hash
(),
Diff
:
head
.
Difficulty
.
String
(),
TotalDiff
:
td
.
String
(),
Txs
:
txs
,
Uncles
:
uncles
,
},
}
report
:=
map
[
string
][]
interface
{}{
"emit"
:
[]
interface
{}{
"block"
,
stats
},
}
if
err
:=
out
.
Encode
(
report
);
err
!=
nil
{
return
err
}
return
nil
}
// pendStats is the information to report about pending transactions.
type
pendStats
struct
{
Pending
int
`json:"pending"`
}
// reportPending retrieves the current number of pending transactions and reports
// it to the stats server.
func
(
s
*
Service
)
reportPending
(
out
*
json
.
Encoder
)
error
{
// Retrieve the pending count from the local blockchain
var
pending
int
if
s
.
eth
!=
nil
{
pending
,
_
=
s
.
eth
.
TxPool
()
.
Stats
()
}
else
{
pending
=
s
.
les
.
TxPool
()
.
Stats
()
}
// Assemble the transaction stats and send it to the server
stats
:=
map
[
string
]
interface
{}{
"id"
:
s
.
node
,
"stats"
:
&
pendStats
{
Pending
:
pending
,
},
}
report
:=
map
[
string
][]
interface
{}{
"emit"
:
[]
interface
{}{
"pending"
,
stats
},
}
if
err
:=
out
.
Encode
(
report
);
err
!=
nil
{
return
err
}
return
nil
}
// blockStats is the information to report about the local node.
type
nodeStats
struct
{
Active
bool
`json:"active"`
Syncing
bool
`json:"syncing"`
Mining
bool
`json:"mining"`
Hashrate
int
`json:"hashrate"`
Peers
int
`json:"peers"`
GasPrice
int
`json:"gasPrice"`
Uptime
int
`json:"uptime"`
}
// reportPending retrieves various stats about the node at the networking and
// mining layer and reports it to the stats server.
func
(
s
*
Service
)
reportStats
(
out
*
json
.
Encoder
)
error
{
// Gather the syncing and mining infos from the local miner instance
var
(
mining
bool
hashrate
int
syncing
bool
gasprice
int
)
if
s
.
eth
!=
nil
{
mining
=
s
.
eth
.
Miner
()
.
Mining
()
hashrate
=
int
(
s
.
eth
.
Miner
()
.
HashRate
())
sync
:=
s
.
eth
.
Downloader
()
.
Progress
()
syncing
=
s
.
eth
.
BlockChain
()
.
CurrentHeader
()
.
Number
.
Uint64
()
>=
sync
.
HighestBlock
gasprice
=
int
(
s
.
eth
.
Miner
()
.
GasPrice
()
.
Uint64
())
}
else
{
sync
:=
s
.
les
.
Downloader
()
.
Progress
()
syncing
=
s
.
les
.
BlockChain
()
.
CurrentHeader
()
.
Number
.
Uint64
()
>=
sync
.
HighestBlock
}
stats
:=
map
[
string
]
interface
{}{
"id"
:
s
.
node
,
"stats"
:
&
nodeStats
{
Active
:
true
,
Mining
:
mining
,
Hashrate
:
hashrate
,
Peers
:
s
.
server
.
PeerCount
(),
GasPrice
:
gasprice
,
Syncing
:
syncing
,
Uptime
:
100
,
},
}
report
:=
map
[
string
][]
interface
{}{
"emit"
:
[]
interface
{}{
"stats"
,
stats
},
}
if
err
:=
out
.
Encode
(
report
);
err
!=
nil
{
return
err
}
return
nil
}
les/backend.go
View file @
4c8c5e2f
...
@@ -180,6 +180,7 @@ func (s *LightEthereum) BlockChain() *light.LightChain { return s.blockchai
...
@@ -180,6 +180,7 @@ func (s *LightEthereum) BlockChain() *light.LightChain { return s.blockchai
func
(
s
*
LightEthereum
)
TxPool
()
*
light
.
TxPool
{
return
s
.
txPool
}
func
(
s
*
LightEthereum
)
TxPool
()
*
light
.
TxPool
{
return
s
.
txPool
}
func
(
s
*
LightEthereum
)
LesVersion
()
int
{
return
int
(
s
.
protocolManager
.
SubProtocols
[
0
]
.
Version
)
}
func
(
s
*
LightEthereum
)
LesVersion
()
int
{
return
int
(
s
.
protocolManager
.
SubProtocols
[
0
]
.
Version
)
}
func
(
s
*
LightEthereum
)
Downloader
()
*
downloader
.
Downloader
{
return
s
.
protocolManager
.
downloader
}
func
(
s
*
LightEthereum
)
Downloader
()
*
downloader
.
Downloader
{
return
s
.
protocolManager
.
downloader
}
func
(
s
*
LightEthereum
)
EventMux
()
*
event
.
TypeMux
{
return
s
.
eventMux
}
// Protocols implements node.Service, returning all the currently configured
// Protocols implements node.Service, returning all the currently configured
// network protocols to start.
// network protocols to start.
...
...
mobile/geth.go
View file @
4c8c5e2f
...
@@ -27,6 +27,7 @@ import (
...
@@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethstats"
"github.com/ethereum/go-ethereum/les"
"github.com/ethereum/go-ethereum/les"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/p2p/nat"
...
@@ -65,6 +66,12 @@ type NodeConfig struct {
...
@@ -65,6 +66,12 @@ type NodeConfig struct {
// A minimum of 16MB is always reserved.
// A minimum of 16MB is always reserved.
EthereumDatabaseCache
int
EthereumDatabaseCache
int
// EthereumNetStats is a netstats connection string to use to report various
// chain, transaction and node stats to a monitoring server.
//
// It has the form "nodename:secret@host:port"
EthereumNetStats
string
// WhisperEnabled specifies whether the node should run the Whisper protocol.
// WhisperEnabled specifies whether the node should run the Whisper protocol.
WhisperEnabled
bool
WhisperEnabled
bool
}
}
...
@@ -106,6 +113,7 @@ func NewNode(datadir string, config *NodeConfig) (*Node, error) {
...
@@ -106,6 +113,7 @@ func NewNode(datadir string, config *NodeConfig) (*Node, error) {
// Create the empty networking stack
// Create the empty networking stack
nodeConf
:=
&
node
.
Config
{
nodeConf
:=
&
node
.
Config
{
Name
:
clientIdentifier
,
Name
:
clientIdentifier
,
Version
:
params
.
Version
,
DataDir
:
datadir
,
DataDir
:
datadir
,
KeyStoreDir
:
filepath
.
Join
(
datadir
,
"keystore"
),
// Mobile should never use internal keystores!
KeyStoreDir
:
filepath
.
Join
(
datadir
,
"keystore"
),
// Mobile should never use internal keystores!
NoDiscovery
:
true
,
NoDiscovery
:
true
,
...
@@ -150,6 +158,17 @@ func NewNode(datadir string, config *NodeConfig) (*Node, error) {
...
@@ -150,6 +158,17 @@ func NewNode(datadir string, config *NodeConfig) (*Node, error) {
});
err
!=
nil
{
});
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"ethereum init: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"ethereum init: %v"
,
err
)
}
}
// If netstats reporting is requested, do it
if
config
.
EthereumNetStats
!=
""
{
if
err
:=
stack
.
Register
(
func
(
ctx
*
node
.
ServiceContext
)
(
node
.
Service
,
error
)
{
var
lesServ
*
les
.
LightEthereum
ctx
.
Service
(
&
lesServ
)
return
ethstats
.
New
(
config
.
EthereumNetStats
,
nil
,
lesServ
)
});
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"netstats init: %v"
,
err
)
}
}
}
}
// Register the Whisper protocol if requested
// Register the Whisper protocol if requested
if
config
.
WhisperEnabled
{
if
config
.
WhisperEnabled
{
...
...
cmd/util
s/version.go
→
param
s/version.go
View file @
4c8c5e2f
...
@@ -14,18 +14,9 @@
...
@@ -14,18 +14,9 @@
// You should have received a copy of the GNU General Public License
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
// Package utils contains internal helper functions for go-ethereum commands.
package
params
package
utils
import
(
import
"fmt"
"fmt"
"runtime"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
)
const
(
const
(
VersionMajor
=
1
// Major version component of the current release
VersionMajor
=
1
// Major version component of the current release
...
@@ -42,23 +33,3 @@ var Version = func() string {
...
@@ -42,23 +33,3 @@ var Version = func() string {
}
}
return
v
return
v
}()
}()
// MakeDefaultExtraData returns the default Ethereum block extra data blob.
func
MakeDefaultExtraData
(
clientIdentifier
string
)
[]
byte
{
var
clientInfo
=
struct
{
Version
uint
Name
string
GoVersion
string
Os
string
}{
uint
(
VersionMajor
<<
16
|
VersionMinor
<<
8
|
VersionPatch
),
clientIdentifier
,
runtime
.
Version
(),
runtime
.
GOOS
}
extra
,
err
:=
rlp
.
EncodeToBytes
(
clientInfo
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Warn
)
.
Infoln
(
"error setting canonical miner information:"
,
err
)
}
if
uint64
(
len
(
extra
))
>
params
.
MaximumExtraDataSize
.
Uint64
()
{
glog
.
V
(
logger
.
Warn
)
.
Infoln
(
"error setting canonical miner information: extra exceeds"
,
params
.
MaximumExtraDataSize
)
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"extra: %x
\n
"
,
extra
)
return
nil
}
return
extra
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment