good morning!!!!

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • github/maticnetwork/bor
  • open/bor
2 results
Show changes
Showing
with 644 additions and 27 deletions
# Peers add
The ```peers add <enode>``` command joins the local client to another remote peer.
## Arguments
- ```trusted```: Whether the peer is added as a trusted peer.
# Peers list
The ```peers list``` command lists the connected peers.
# Peers remove
The ```peers remove <enode>``` command disconnects the local client from a connected peer if exists.
# Peers status
The ```peers status <peer id>``` command displays the status of a peer by its id.
# Server
The ```bor server``` command runs the Bor client.
## General Options
- ```chain```: Name of the chain to sync (mainnet or mumbai).
- ```log-level```: Set log level for the server (info, warn, debug, trace).
- ```datadir```: Path of the data directory to store information (defaults to $HOME).
- ```config```: List of files that contain the configuration.
- ```syncmode```: Blockchain sync mode ("fast", "full", "snap" or "light").
- ```gcmode```: Blockchain garbage collection mode ("full", "archive").
- ```whitelist```: Comma separated block number-to-hash mappings to enforce (<number>=<hash>).
- ```snapshot```: Enables snapshot-database mode (default = enable).
- ```bor.heimdall```: URL of Heimdall service.
- ```bor.withoutheimdall```: Run without Heimdall service (for testing purpose).
- ```ethstats```: Reporting URL of a ethstats service (nodename:secret@host:port).
- ```gpo.blocks```: Number of recent blocks to check for gas prices.
- ```gpo.percentile```: Suggested gas price is the given percentile of a set of recent transaction gas prices.
- ```gpo.maxprice```: Maximum gas price will be recommended by gpo.
- ```gpo.ignoreprice```: Gas price below which gpo will ignore transactions.
- ```grpc.addr```: Address and port to bind the GRPC server.
### Transaction Pool Options
- ```txpool.locals```: Comma separated accounts to treat as locals (no flush, priority inclusion).
- ```txpool.nolocals```: Disables price exemptions for locally submitted transactions
- ```txpool.journal```: Disk journal for local transaction to survive node restarts
- ```txpool.rejournal```: Time interval to regenerate the local transaction journal
- ```txpool.pricelimit```: Minimum gas price limit to enforce for acceptance into the pool
- ```txpool.pricebump```: Price bump percentage to replace an already existing transaction
- ```txpool.accountslots```: Minimum number of executable transaction slots guaranteed per account
- ```txpool.globalslots```: Maximum number of executable transaction slots for all accounts
- ```txpool.accountqueue```: Maximum number of non-executable transaction slots permitted per account
- ```txpool.globalqueue```: Maximum number of non-executable transaction slots for all accounts
- ```txpool.lifetime```: Maximum amount of time non-executable transaction are queued
### Sealer Options
- ```mine```: Enable sealing.
- ```miner.etherbase```: Public address for block mining rewards (default = first account)
- ```miner.extradata```: Block extra data set by the miner (default = client version).
- ```miner.gaslimit```: Target gas ceiling for mined blocks.
- ```miner.gasprice```: Minimum gas price for mining a transaction.
### Cache Options
- ```cache```: Megabytes of memory allocated to internal caching (default = 4096 mainnet full node).
- ```cache.database```: Percentage of cache memory allowance to use for database io.
- ```cache.trie```: Percentage of cache memory allowance to use for trie caching (default = 15% full mode, 30% archive mode).
- ```cache.trie.journal```: Disk journal directory for trie cache to survive node restarts.
- ```cache.trie.rejournal```: Time interval to regenerate the trie cache journal.
- ```cache.gc```: Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode).
- ```cache.snapshot```: Percentage of cache memory allowance to use for snapshot caching (default = 10% full mode, 20% archive mode).
- ```cache.noprefetch```: Disable heuristic state prefetch during block import (less CPU and disk IO, more time waiting for data).
- ```cache.preimages```: Enable recording the SHA3/keccak preimages of trie keys.
- ```txlookuplimit```: Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain).
### JsonRPC Options
- ```rpc.gascap```: Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite).
- ```rpc.txfeecap```: Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap).
- ```ipcdisable```: Disable the IPC-RPC server.
- ```ipcpath```: Filename for IPC socket/pipe within the datadir (explicit paths escape it).
- ```jsonrpc.corsdomain```: Comma separated list of domains from which to accept cross.
- ```jsonrpc.vhosts```: Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.
- ```http```: Enable the HTTP-RPC server.
- ```http.addr```: HTTP-RPC server listening interface.
- ```http.port```: HTTP-RPC server listening port.
- ```http.rpcprefix```: HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths.
- ```http.modules```: API's offered over the HTTP-RPC interface.
- ```ws```: Enable the WS-RPC server.
- ```ws.addr```: WS-RPC server listening interface.
- ```ws.port```: WS-RPC server listening port.
- ```ws.rpcprefix```: HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths.
- ```ws.modules```: API's offered over the WS-RPC interface.
- ```graphql```: Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well.
### P2P Options
- ```bind```: Network binding address
- ```port```: Network listening port
- ```bootnodes```: Comma separated enode URLs for P2P discovery bootstrap
- ```maxpeers```: "Maximum number of network peers (network disabled if set to 0)
- ```maxpendpeers```: Maximum number of pending connection attempts (defaults used if set to 0)
- ```nat```: "NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>)
- ```nodiscover```: "Disables the peer discovery mechanism (manual peer addition)
- ```v5disc```: "Enables the experimental RLPx V5 (Topic Discovery) mechanism
### Telemetry Options
- ```metrics```: Enable metrics collection and reporting.
- ```metrics.expensive```: Enable expensive metrics collection and reporting.
- ```metrics.influxdb```: Enable metrics export/push to an external InfluxDB database (v1).
- ```metrics.influxdb.endpoint```: InfluxDB API endpoint to report metrics to.
- ```metrics.influxdb.database```: InfluxDB database name to push reported metrics to.
- ```metrics.influxdb.username```: Username to authorize access to the database.
- ```metrics.influxdb.password```: Password to authorize access to the database.
- ```metrics.influxdb.tags```: Comma-separated InfluxDB tags (key/values) attached to all measurements.
- ```metrics.influxdbv2```: Enable metrics export/push to an external InfluxDB v2 database.
- ```metrics.influxdb.token```: Token to authorize access to the database (v2 only).
- ```metrics.influxdb.bucket```: InfluxDB bucket name to push reported metrics to (v2 only).
- ```metrics.influxdb.organization```: InfluxDB organization name (v2 only).
### Account Management Options
- ```unlock```: "Comma separated list of accounts to unlock.
- ```password```: Password file to use for non-interactive password input.
- ```allow-insecure-unlock```: Allow insecure account unlocking when account-related RPCs are exposed by http.
- ```lightkdf```: Reduce key-derivation RAM & CPU usage at some expense of KDF strength.
## Usage
Use multiple files to configure the client:
```
$ bor server --config ./legacy-config.toml --config ./config2.hcl
```
# Status
The ```status``` command outputs the status of the client.
# Version
The ```bor version``` command outputs the version of the binary.
## Usage
```
$ bor version
0.2.9-stable
```
# Config
Toml files format used in geth are being deprecated.
Bor uses uses JSON and [HCL](https://github.com/hashicorp/hcl) formats to create configuration files. This is the format in HCL alongside the default values:
```
chain = "mainnet"
log-level = "info"
data-dir = ""
sync-mode = "fast"
gc-mode = "full"
snapshot = true
ethstats = ""
whitelist = {}
p2p {
max-peers = 30
max-pend-peers = 50
bind = "0.0.0.0"
port = 30303
no-discover = false
nat = "any"
discovery {
v5-enabled = false
bootnodes = []
bootnodesv4 = []
bootnodesv5 = []
staticNodes = []
trustedNodes = []
dns = []
}
}
heimdall {
url = "http://localhost:1317"
without = false
}
txpool {
locals = []
no-locals = false
journal = ""
rejournal = "1h"
price-limit = 1
price-bump = 10
account-slots = 16
global-slots = 4096
account-queue = 64
global-queue = 1024
lifetime = "3h"
}
sealer {
enabled = false
etherbase = ""
gas-ceil = 8000000
extra-data = ""
}
gpo {
blocks = 20
percentile = 60
}
jsonrpc {
ipc-disable = false
ipc-path = ""
modules = ["web3", "net"]
cors = ["*"]
vhost = ["*"]
http {
enabled = false
port = 8545
prefix = ""
host = "localhost"
}
ws {
enabled = false
port = 8546
prefix = ""
host = "localhost"
}
graphqh {
enabled = false
}
}
telemetry {
enabled = false
expensive = false
influxdb {
v1-enabled = false
endpoint = ""
database = ""
username = ""
password = ""
v2-enabled = false
token = ""
bucket = ""
organization = ""
}
}
cache {
cache = 1024
perc-database = 50
perc-trie = 15
perc-gc = 25
perc-snapshot = 10
journal = "triecache"
rejournal = "60m"
no-prefetch = false
preimages = false
tx-lookup-limit = 2350000
}
accounts {
unlock = []
password-file = ""
allow-insecure-unlock = false
use-lightweight-kdf = false
}
grpc {
addr = ":3131"
}
```
...@@ -581,10 +581,12 @@ func (s *Ethereum) Stop() error { ...@@ -581,10 +581,12 @@ func (s *Ethereum) Stop() error {
// Then stop everything else. // Then stop everything else.
s.bloomIndexer.Close() s.bloomIndexer.Close()
close(s.closeBloomHandler) close(s.closeBloomHandler)
// closing consensus engine first, as miner has deps on it
s.engine.Close()
s.txPool.Stop() s.txPool.Stop()
s.miner.Close()
s.blockchain.Stop() s.blockchain.Stop()
s.engine.Close() s.miner.Close()
rawdb.PopUncleanShutdownMarker(s.chainDb) rawdb.PopUncleanShutdownMarker(s.chainDb)
s.chainDb.Close() s.chainDb.Close()
s.eventMux.Stop() s.eventMux.Stop()
......
...@@ -67,3 +67,8 @@ func (b *EthAPIBackend) GetBorBlockTransactionWithBlockHash(ctx context.Context, ...@@ -67,3 +67,8 @@ func (b *EthAPIBackend) GetBorBlockTransactionWithBlockHash(ctx context.Context,
func (b *EthAPIBackend) SubscribeStateSyncEvent(ch chan<- core.StateSyncEvent) event.Subscription { func (b *EthAPIBackend) SubscribeStateSyncEvent(ch chan<- core.StateSyncEvent) event.Subscription {
return b.eth.BlockChain().SubscribeStateSyncEvent(ch) return b.eth.BlockChain().SubscribeStateSyncEvent(ch)
} }
// SubscribeChain2HeadEvent subscribes to reorg/head/fork event
func (b *EthAPIBackend) SubscribeChain2HeadEvent(ch chan<- core.Chain2HeadEvent) event.Subscription {
return b.eth.BlockChain().SubscribeChain2HeadEvent(ch)
}
...@@ -110,6 +110,8 @@ func generateTestChainWithFork(n int, fork int) (*core.Genesis, []*types.Block, ...@@ -110,6 +110,8 @@ func generateTestChainWithFork(n int, fork int) (*core.Genesis, []*types.Block,
*/ */
func TestEth2AssembleBlock(t *testing.T) { func TestEth2AssembleBlock(t *testing.T) {
t.Skip("bor due to burn contract")
genesis, blocks := generateTestChain() genesis, blocks := generateTestChain()
n, ethservice := startEthService(t, genesis, blocks[1:9]) n, ethservice := startEthService(t, genesis, blocks[1:9])
defer n.Close() defer n.Close()
...@@ -137,6 +139,8 @@ func TestEth2AssembleBlock(t *testing.T) { ...@@ -137,6 +139,8 @@ func TestEth2AssembleBlock(t *testing.T) {
} }
func TestEth2AssembleBlockWithAnotherBlocksTxs(t *testing.T) { func TestEth2AssembleBlockWithAnotherBlocksTxs(t *testing.T) {
t.Skip("bor due to burn contract")
genesis, blocks := generateTestChain() genesis, blocks := generateTestChain()
n, ethservice := startEthService(t, genesis, blocks[1:9]) n, ethservice := startEthService(t, genesis, blocks[1:9])
defer n.Close() defer n.Close()
......
...@@ -229,7 +229,9 @@ func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, et ...@@ -229,7 +229,9 @@ func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, et
return clique.New(chainConfig.Clique, db) return clique.New(chainConfig.Clique, db)
} }
// If Matic bor consensus is requested, set it up // If Matic bor consensus is requested, set it up
if chainConfig.Bor != nil { // In order to pass the ethereum transaction tests, we need to set the burn contract which is in the bor config
// Then, bor != nil will also be enabled for ethash and clique. Only enable Bor for real if there is a validator contract present.
if chainConfig.Bor != nil && chainConfig.Bor.ValidatorContract != "" {
return bor.New(chainConfig, db, blockchainAPI, ethConfig.HeimdallURL, ethConfig.WithoutHeimdall) return bor.New(chainConfig, db, blockchainAPI, ethConfig.HeimdallURL, ethConfig.WithoutHeimdall)
} }
// Otherwise assume proof-of-work // Otherwise assume proof-of-work
......
...@@ -40,7 +40,8 @@ import ( ...@@ -40,7 +40,8 @@ import (
) )
var ( var (
deadline = 5 * time.Minute deadline = 5 * time.Minute
borLogs bool = true
) )
type testBackend struct { type testBackend struct {
...@@ -174,7 +175,7 @@ func TestBlockSubscription(t *testing.T) { ...@@ -174,7 +175,7 @@ func TestBlockSubscription(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
genesis = (&core.Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db) genesis = (&core.Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
chain, _ = core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {}) chain, _ = core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {})
chainEvents = []core.ChainEvent{} chainEvents = []core.ChainEvent{}
...@@ -226,7 +227,7 @@ func TestPendingTxFilter(t *testing.T) { ...@@ -226,7 +227,7 @@ func TestPendingTxFilter(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
transactions = []*types.Transaction{ transactions = []*types.Transaction{
types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil), types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
...@@ -281,7 +282,7 @@ func TestLogFilterCreation(t *testing.T) { ...@@ -281,7 +282,7 @@ func TestLogFilterCreation(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
testCases = []struct { testCases = []struct {
crit FilterCriteria crit FilterCriteria
...@@ -325,7 +326,7 @@ func TestInvalidLogFilterCreation(t *testing.T) { ...@@ -325,7 +326,7 @@ func TestInvalidLogFilterCreation(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
) )
// different situations where log filter creation should fail. // different situations where log filter creation should fail.
...@@ -347,7 +348,7 @@ func TestInvalidGetLogsRequest(t *testing.T) { ...@@ -347,7 +348,7 @@ func TestInvalidGetLogsRequest(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111") blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
) )
...@@ -372,7 +373,7 @@ func TestLogFilter(t *testing.T) { ...@@ -372,7 +373,7 @@ func TestLogFilter(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111") firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222") secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222")
...@@ -486,7 +487,7 @@ func TestPendingLogsSubscription(t *testing.T) { ...@@ -486,7 +487,7 @@ func TestPendingLogsSubscription(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111") firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222") secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222")
...@@ -670,7 +671,7 @@ func TestPendingTxFilterDeadlock(t *testing.T) { ...@@ -670,7 +671,7 @@ func TestPendingTxFilterDeadlock(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, timeout) api = NewPublicFilterAPI(backend, false, timeout, borLogs)
done = make(chan struct{}) done = make(chan struct{})
) )
......
...@@ -35,7 +35,7 @@ import ( ...@@ -35,7 +35,7 @@ import (
const sampleNumber = 3 // Number of transactions sampled in a block const sampleNumber = 3 // Number of transactions sampled in a block
var ( var (
DefaultMaxPrice = big.NewInt(500 * params.GWei) DefaultMaxPrice = big.NewInt(5000 * params.GWei)
DefaultIgnorePrice = big.NewInt(2 * params.Wei) DefaultIgnorePrice = big.NewInt(2 * params.Wei)
) )
......
...@@ -234,6 +234,8 @@ func generateTestChain() (*core.Genesis, []*types.Block) { ...@@ -234,6 +234,8 @@ func generateTestChain() (*core.Genesis, []*types.Block) {
} }
func TestEthClient(t *testing.T) { func TestEthClient(t *testing.T) {
t.Skip("bor due to burn contract")
backend, chain := newTestBackend(t) backend, chain := newTestBackend(t)
client, _ := backend.Attach() client, _ := backend.Attach()
defer backend.Close() defer backend.Close()
......
...@@ -89,6 +89,8 @@ func generateTestChain() (*core.Genesis, []*types.Block) { ...@@ -89,6 +89,8 @@ func generateTestChain() (*core.Genesis, []*types.Block) {
} }
func TestGethClient(t *testing.T) { func TestGethClient(t *testing.T) {
t.Skip("bor due to burn contract")
backend, _ := newTestBackend(t) backend, _ := newTestBackend(t)
client, err := backend.Attach() client, err := backend.Attach()
if err != nil { if err != nil {
......
...@@ -57,6 +57,9 @@ const ( ...@@ -57,6 +57,9 @@ const (
txChanSize = 4096 txChanSize = 4096
// chainHeadChanSize is the size of channel listening to ChainHeadEvent. // chainHeadChanSize is the size of channel listening to ChainHeadEvent.
chainHeadChanSize = 10 chainHeadChanSize = 10
// chain2HeadChanSize is the size of channel listening to Chain2HeadEvent.
chain2HeadChanSize = 10
) )
// backend encompasses the bare-minimum functionality needed for ethstats reporting // backend encompasses the bare-minimum functionality needed for ethstats reporting
...@@ -68,6 +71,9 @@ type backend interface { ...@@ -68,6 +71,9 @@ type backend interface {
GetTd(ctx context.Context, hash common.Hash) *big.Int GetTd(ctx context.Context, hash common.Hash) *big.Int
Stats() (pending int, queued int) Stats() (pending int, queued int)
SyncProgress() ethereum.SyncProgress SyncProgress() ethereum.SyncProgress
// Bor
SubscribeChain2HeadEvent(ch chan<- core.Chain2HeadEvent) event.Subscription
} }
// fullNodeBackend encompasses the functionality necessary for a full node // fullNodeBackend encompasses the functionality necessary for a full node
...@@ -96,6 +102,9 @@ type Service struct { ...@@ -96,6 +102,9 @@ type Service struct {
headSub event.Subscription headSub event.Subscription
txSub event.Subscription txSub event.Subscription
//bor related sub
chain2headSub event.Subscription
} }
// connWrapper is a wrapper to prevent concurrent-write or concurrent-read on the // connWrapper is a wrapper to prevent concurrent-write or concurrent-read on the
...@@ -195,7 +204,9 @@ func (s *Service) Start() error { ...@@ -195,7 +204,9 @@ func (s *Service) Start() error {
s.headSub = s.backend.SubscribeChainHeadEvent(chainHeadCh) s.headSub = s.backend.SubscribeChainHeadEvent(chainHeadCh)
txEventCh := make(chan core.NewTxsEvent, txChanSize) txEventCh := make(chan core.NewTxsEvent, txChanSize)
s.txSub = s.backend.SubscribeNewTxsEvent(txEventCh) s.txSub = s.backend.SubscribeNewTxsEvent(txEventCh)
go s.loop(chainHeadCh, txEventCh) chain2HeadCh := make(chan core.Chain2HeadEvent, chain2HeadChanSize)
s.chain2headSub = s.backend.SubscribeChain2HeadEvent(chain2HeadCh)
go s.loop(chainHeadCh, chain2HeadCh, txEventCh)
log.Info("Stats daemon started") log.Info("Stats daemon started")
return nil return nil
...@@ -211,12 +222,13 @@ func (s *Service) Stop() error { ...@@ -211,12 +222,13 @@ func (s *Service) Stop() error {
// loop keeps trying to connect to the netstats server, reporting chain events // loop keeps trying to connect to the netstats server, reporting chain events
// until termination. // until termination.
func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core.NewTxsEvent) { func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, chain2HeadCh chan core.Chain2HeadEvent, txEventCh chan core.NewTxsEvent) {
// Start a goroutine that exhausts the subscriptions to avoid events piling up // Start a goroutine that exhausts the subscriptions to avoid events piling up
var ( var (
quitCh = make(chan struct{}) quitCh = make(chan struct{})
headCh = make(chan *types.Block, 1) headCh = make(chan *types.Block, 1)
txCh = make(chan struct{}, 1) txCh = make(chan struct{}, 1)
head2Ch = make(chan core.Chain2HeadEvent, 100)
) )
go func() { go func() {
var lastTx mclock.AbsTime var lastTx mclock.AbsTime
...@@ -231,6 +243,13 @@ func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core ...@@ -231,6 +243,13 @@ func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core
default: default:
} }
// Notify of chain2head events, but drop if too frequent
case chain2head := <-chain2HeadCh:
select {
case head2Ch <- chain2head:
default:
}
// Notify of new transaction events, but drop if too frequent // Notify of new transaction events, but drop if too frequent
case <-txEventCh: case <-txEventCh:
if time.Duration(mclock.Now()-lastTx) < time.Second { if time.Duration(mclock.Now()-lastTx) < time.Second {
...@@ -333,6 +352,12 @@ func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core ...@@ -333,6 +352,12 @@ func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core
if err = s.reportPending(conn); err != nil { if err = s.reportPending(conn); err != nil {
log.Warn("Post-block transaction stats report failed", "err", err) log.Warn("Post-block transaction stats report failed", "err", err)
} }
case chain2head := <-head2Ch:
if err = s.reportChain2Head(conn, &chain2head); err != nil {
log.Warn("Reorg stats report failed", "err", err)
}
case <-txCh: case <-txCh:
if err = s.reportPending(conn); err != nil { if err = s.reportPending(conn); err != nil {
log.Warn("Transaction stats report failed", "err", err) log.Warn("Transaction stats report failed", "err", err)
...@@ -750,6 +775,49 @@ func (s *Service) reportPending(conn *connWrapper) error { ...@@ -750,6 +775,49 @@ func (s *Service) reportPending(conn *connWrapper) error {
return conn.WriteJSON(report) return conn.WriteJSON(report)
} }
type blockStub struct {
Hash string `json:"hash"`
Number uint64 `json:"number"`
ParentHash string `json:"parent_hash"`
}
func createStub(b *types.Block) *blockStub {
s := &blockStub{
Hash: b.Hash().String(),
ParentHash: b.ParentHash().String(),
Number: b.NumberU64(),
}
return s
}
type ChainHeadEvent struct {
NewChain []*blockStub `json:"added"`
OldChain []*blockStub `json:"removed"`
Type string `json:"type"`
}
// reportChain2Head checks for reorg and sends current head to stats server.
func (s *Service) reportChain2Head(conn *connWrapper, chain2HeadData *core.Chain2HeadEvent) error {
chainHeadEvent := ChainHeadEvent{
Type: chain2HeadData.Type,
}
for _, block := range chain2HeadData.NewChain {
chainHeadEvent.NewChain = append(chainHeadEvent.NewChain, createStub(block))
}
for _, block := range chain2HeadData.OldChain {
chainHeadEvent.OldChain = append(chainHeadEvent.OldChain, createStub(block))
}
stats := map[string]interface{}{
"id": s.node,
"event": chainHeadEvent,
}
report := map[string][]interface{}{
"emit": {"headEvent", stats},
}
return conn.WriteJSON(report)
}
// nodeStats is the information to report about the local node. // nodeStats is the information to report about the local node.
type nodeStats struct { type nodeStats struct {
Active bool `json:"active"` Active bool `json:"active"`
......
...@@ -25,9 +25,11 @@ require ( ...@@ -25,9 +25,11 @@ require (
github.com/fatih/color v1.7.0 github.com/fatih/color v1.7.0
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
github.com/go-kit/kit v0.9.0 // indirect
github.com/go-logfmt/logfmt v0.5.0 // indirect
github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-ole/go-ole v1.2.1 // indirect
github.com/go-stack/stack v1.8.0 github.com/go-stack/stack v1.8.0
github.com/golang/protobuf v1.4.3 github.com/golang/protobuf v1.5.2
github.com/golang/snappy v0.0.4 github.com/golang/snappy v0.0.4
github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa
github.com/google/uuid v1.1.5 github.com/google/uuid v1.1.5
...@@ -35,19 +37,24 @@ require ( ...@@ -35,19 +37,24 @@ require (
github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29
github.com/hashicorp/go-bexpr v0.1.10 github.com/hashicorp/go-bexpr v0.1.10
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
github.com/hashicorp/hcl/v2 v2.10.1
github.com/holiman/bloomfilter/v2 v2.0.3 github.com/holiman/bloomfilter/v2 v2.0.3
github.com/holiman/uint256 v1.2.0 github.com/holiman/uint256 v1.2.0
github.com/huin/goupnp v1.0.2 github.com/huin/goupnp v1.0.2
github.com/imdario/mergo v0.3.11
github.com/influxdata/influxdb v1.8.3 github.com/influxdata/influxdb v1.8.3
github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/influxdb-client-go/v2 v2.4.0
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e
github.com/julienschmidt/httprouter v1.2.0 github.com/julienschmidt/httprouter v1.3.0
github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559 github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559
github.com/kylelemons/godebug v1.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.8 github.com/mattn/go-colorable v0.1.8
github.com/mattn/go-isatty v0.0.12 github.com/mattn/go-isatty v0.0.12
github.com/mitchellh/cli v1.1.2
github.com/mitchellh/go-grpc-net-conn v0.0.0-20200427190222-eb030e4876f0 // indirect
github.com/mitchellh/go-homedir v1.1.0
github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416
github.com/olekukonko/tablewriter v0.0.5 github.com/olekukonko/tablewriter v0.0.5
...@@ -55,6 +62,7 @@ require ( ...@@ -55,6 +62,7 @@ require (
github.com/prometheus/tsdb v0.7.1 github.com/prometheus/tsdb v0.7.1
github.com/rjeczalik/notify v0.9.1 github.com/rjeczalik/notify v0.9.1
github.com/rs/cors v1.7.0 github.com/rs/cors v1.7.0
github.com/ryanuber/columnize v2.1.2+incompatible
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
...@@ -62,12 +70,17 @@ require ( ...@@ -62,12 +70,17 @@ require (
github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef
github.com/xsleonard/go-merkle v1.1.0 github.com/xsleonard/go-merkle v1.1.0
go.opentelemetry.io/otel v1.2.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.2.0
go.opentelemetry.io/otel/sdk v1.2.0
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912
golang.org/x/text v0.3.6 golang.org/x/text v0.3.6
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
google.golang.org/grpc v1.42.0
google.golang.org/protobuf v1.27.1
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6
gopkg.in/urfave/cli.v1 v1.20.0 gopkg.in/urfave/cli.v1 v1.20.0
......
This diff is collapsed.
package cli
import "github.com/mitchellh/cli"
type Account struct {
UI cli.Ui
}
// Help implements the cli.Command interface
func (a *Account) Help() string {
return `Usage: bor account <subcommand>
This command groups actions to interact with accounts.
List the running deployments:
$ bor account new
Display the status of a specific deployment:
$ bor account import
List the imported accounts in the keystore:
$ bor account list`
}
// Synopsis implements the cli.Command interface
func (a *Account) Synopsis() string {
return "Interact with accounts"
}
// Run implements the cli.Command interface
func (a *Account) Run(args []string) int {
return cli.RunResultHelp
}