merge master

This commit is contained in:
Arpit Temani 2022-01-24 16:11:23 +05:30
commit 560ad7dd9d
73 changed files with 2629 additions and 1300 deletions

View file

@ -16,9 +16,11 @@ builds:
env:
- CC=o64-clang
- CXX=o64-clang++
tags:
- netgo
ldflags:
-s -w
- id: darwin-arm64
main: ./cmd/geth
binary: bor
@ -29,9 +31,11 @@ builds:
env:
- CC=oa64-clang
- CXX=oa64-clang++
tags:
- netgo
ldflags:
-s -w
- id: linux-amd64
main: ./cmd/geth
binary: bor
@ -42,9 +46,11 @@ builds:
env:
- CC=gcc
- CXX=g++
tags:
- netgo
ldflags:
# We need to build a static binary because we are building in a glibc based system and running in a musl container
-s -w -linkmode external -extldflags "-static"
# We need to build a static binary because we are building in a glibc based system and running in a musl container
-s -w -extldflags "-static"
- id: linux-arm64
main: ./cmd/geth
@ -56,9 +62,11 @@ builds:
env:
- CC=aarch64-linux-gnu-gcc
- CXX=aarch64-linux-gnu-g++
tags:
- netgo
ldflags:
# We need to build a static binary because we are building in a glibc based system and running in a musl container
-s -w -linkmode external -extldflags "-static"
# We need to build a static binary because we are building in a glibc based system and running in a musl container
-s -w -extldflags "-static"
nfpms:
- vendor: 0xPolygon
@ -76,6 +84,12 @@ nfpms:
- src: builder/files/bor.service
dst: /lib/systemd/system/bor.service
type: config
- src: builder/files/genesis-mainnet-v1.json
dst: /etc/bor/genesis-mainnet-v1.json
type: config
- src: builder/files/genesis-testnet-v4.json
dst: /etc/bor/genesis-testnet-v4.json
type: config
overrides:
rpm:
@ -95,7 +109,10 @@ dockers:
- linux-amd64
build_flag_templates:
- --platform=linux/amd64
extra_files:
- builder/files/genesis-mainnet-v1.json
- builder/files/genesis-testnet-v4.json
- image_templates:
- 0xpolygon/{{ .ProjectName }}:{{ .Version }}-arm64
dockerfile: Dockerfile.release
@ -104,7 +121,10 @@ dockers:
ids:
- linux-arm64
build_flag_templates:
- --platform=linux/arm64
- --platform=linux/arm64/v8
extra_files:
- builder/files/genesis-mainnet-v1.json
- builder/files/genesis-testnet-v4.json
docker_manifests:
- name_template: 0xpolygon/{{ .ProjectName }}:{{ .Version }}

View file

@ -1,7 +1,10 @@
FROM alpine:3.14
RUN apk add --no-cache ca-certificates
RUN apk add --no-cache ca-certificates && \
mkdir -p /etc/bor
COPY bor /usr/local/bin/
COPY builder/files/genesis-mainnet-v1.json /etc/bor/
COPY builder/files/genesis-testnet-v4.json /etc/bor/
EXPOSE 8545 8546 8547 30303 30303/udp
ENTRYPOINT ["bor"]

View file

@ -13,9 +13,6 @@ GO ?= latest
GORUN = env GO111MODULE=on go run
GOPATH = $(shell go env GOPATH)
protoc:
protoc --go_out=. --go-grpc_out=. ./command/server/proto/*.proto
bor:
$(GORUN) build/ci.go install ./cmd/geth
mkdir -p $(GOPATH)/bin/
@ -28,6 +25,9 @@ bor-all:
cp $(GOBIN)/geth $(GOBIN)/bor
cp $(GOBIN)/* $(GOPATH)/bin/
protoc:
protoc --go_out=. --go-grpc_out=. ./command/server/proto/*.proto
geth:
$(GORUN) build/ci.go install ./cmd/geth
@echo "Done building."
@ -48,10 +48,9 @@ ios:
@echo "Done building."
@echo "Import \"$(GOBIN)/Geth.framework\" to use the library."
test: all
# $(GORUN) build/ci.go test
go test github.com/ethereum/go-ethereum/consensus/bor -v
go test github.com/ethereum/go-ethereum/tests/bor -v
test:
# Skip mobile and cmd tests since they are being deprecated
go test -v $$(go list ./... | grep -v go-ethereum/cmd/)
lint: ## Run linters.
$(GORUN) build/ci.go lint

View file

@ -6,11 +6,21 @@
[Service]
Restart=on-failure
RestartSec=5s
WorkingDirectory=$NODE_DIR
EnvironmentFile=/etc/matic/metadata
ExecStart=/usr/local/bin/bor $VALIDATOR_ADDRESS
ExecStart=/usr/local/bin/bor \
--bor-mumbai \
# --bor-mainnet \
--datadir /var/lib/bor/data \
--bootnodes "enode://0cb82b395094ee4a2915e9714894627de9ed8498fb881cec6db7c65e8b9a5bd7f2f25cc84e71e89d0947e51c76e85d0847de848c7782b13c0255247a6758178c@44.232.55.71:30303,enode://88116f4295f5a31538ae409e4d44ad40d22e44ee9342869e7d68bdec55b0f83c1530355ce8b41fbec0928a7d75a5745d528450d30aec92066ab6ba1ee351d710@159.203.9.164:30303"
# Validator params
# Uncomment and configure the following lines in case you run a validator
# --keystore /var/lib/bor/keystore \
# --unlock [VALIDATOR ADDRESS] \
# --password /var/lib/bor/password.txt \
# --allow-insecure-unlock \
# --nodiscover --maxpeers 1 \
# --mine
Type=simple
User=$USER
User=root
KillSignal=SIGINT
TimeoutStopSec=120

View file

@ -15,10 +15,21 @@
"londonBlock": 23850000,
"bor": {
"jaipurBlock": 23850000,
<<<<<<< HEAD
"period": 2,
"producerDelay": 6,
"sprint": 64,
"backupMultiplier": 2,
=======
"period": {
"0": 2
},
"producerDelay": 6,
"sprint": 64,
"backupMultiplier": {
"0": 2
},
>>>>>>> 2d84249492818622540ddf5136234fa734e5950a
"validatorContract": "0x0000000000000000000000000000000000001000",
"stateReceiverContract": "0x0000000000000000000000000000000000001001",
"overrideStateSyncRecords": {

File diff suppressed because one or more lines are too long

11
cmd/cli/main.go Normal file
View file

@ -0,0 +1,11 @@
package main
import (
"os"
"github.com/ethereum/go-ethereum/internal/cli"
)
func main() {
os.Exit(cli.Run(os.Args[1:]))
}

View file

@ -347,7 +347,7 @@ func setDefaultMumbaiGethConfig(ctx *cli.Context, config *gethConfig) {
config.Node.HTTPPort = 8545
config.Node.IPCPath = utils.MakeDataDir(ctx) + "/bor.ipc"
config.Node.HTTPModules = []string{"eth", "net", "web3", "txpool", "bor"}
config.Eth.SyncMode = downloader.SnapSync
config.Eth.SyncMode = downloader.FullSync
config.Eth.NetworkId = 80001
config.Eth.Miner.GasCeil = 20000000
//--miner.gastarget is depreceated, No longed used
@ -370,7 +370,7 @@ func setDefaultBorMainnetGethConfig(ctx *cli.Context, config *gethConfig) {
config.Node.HTTPPort = 8545
config.Node.IPCPath = utils.MakeDataDir(ctx) + "/bor.ipc"
config.Node.HTTPModules = []string{"eth", "net", "web3", "txpool", "bor"}
config.Eth.SyncMode = downloader.SnapSync
config.Eth.SyncMode = downloader.FullSync
config.Eth.NetworkId = 137
config.Eth.Miner.GasCeil = 20000000
//--miner.gastarget is depreceated, No longed used

View file

@ -1645,13 +1645,11 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
cfg.NetworkId = 80001
}
cfg.Genesis = core.DefaultMumbaiGenesisBlock()
SetDNSDiscoveryDefaults(cfg, params.MumbaiGenesisHash)
case ctx.GlobalBool(BorMainnetFlag.Name):
if !ctx.GlobalIsSet(BorMainnetFlag.Name) {
cfg.NetworkId = 137
}
cfg.Genesis = core.DefaultBorMainnetGenesisBlock()
SetDNSDiscoveryDefaults(cfg, params.BorMainnetGenesisHash)
case ctx.GlobalBool(DeveloperFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 1337

File diff suppressed because it is too large Load diff

View file

@ -1,109 +0,0 @@
package server
import (
"context"
"encoding/hex"
"fmt"
"strings"
"github.com/ethereum/go-ethereum/command/server/pprof"
"github.com/ethereum/go-ethereum/command/server/proto"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
)
func (s *Server) Pprof(ctx context.Context, req *proto.PprofRequest) (*proto.PprofResponse, error) {
var payload []byte
var headers map[string]string
var err error
switch req.Type {
case proto.PprofRequest_CPU:
payload, headers, err = pprof.CPUProfile(ctx, int(req.Seconds))
case proto.PprofRequest_TRACE:
payload, headers, err = pprof.Trace(ctx, int(req.Seconds))
case proto.PprofRequest_LOOKUP:
payload, headers, err = pprof.Profile(req.Profile, 0, 0)
}
if err != nil {
return nil, err
}
resp := &proto.PprofResponse{
Payload: hex.EncodeToString(payload),
Headers: headers,
}
return resp, nil
}
func (s *Server) PeersAdd(ctx context.Context, req *proto.PeersAddRequest) (*proto.PeersAddResponse, error) {
node, err := enode.Parse(enode.ValidSchemes, req.Enode)
if err != nil {
return nil, fmt.Errorf("invalid enode: %v", err)
}
srv := s.node.Server()
if req.Trusted {
srv.AddTrustedPeer(node)
} else {
srv.AddPeer(node)
}
return &proto.PeersAddResponse{}, nil
}
func (s *Server) PeersRemove(ctx context.Context, req *proto.PeersRemoveRequest) (*proto.PeersRemoveResponse, error) {
node, err := enode.Parse(enode.ValidSchemes, req.Enode)
if err != nil {
return nil, fmt.Errorf("invalid enode: %v", err)
}
srv := s.node.Server()
if req.Trusted {
srv.RemoveTrustedPeer(node)
} else {
srv.RemovePeer(node)
}
return &proto.PeersRemoveResponse{}, nil
}
func (s *Server) PeersList(ctx context.Context, req *proto.PeersListRequest) (*proto.PeersListResponse, error) {
resp := &proto.PeersListResponse{}
peers := s.node.Server().PeersInfo()
for _, p := range peers {
resp.Peers = append(resp.Peers, peerInfoToPeer(p))
}
return resp, nil
}
func (s *Server) PeersStatus(ctx context.Context, req *proto.PeersStatusRequest) (*proto.PeersStatusResponse, error) {
var peerInfo *p2p.PeerInfo
for _, p := range s.node.Server().PeersInfo() {
if strings.HasPrefix(p.ID, req.Enode) {
if peerInfo != nil {
return nil, fmt.Errorf("more than one peer with the same prefix")
}
peerInfo = p
}
}
resp := &proto.PeersStatusResponse{}
if peerInfo != nil {
resp.Peer = peerInfoToPeer(peerInfo)
}
return resp, nil
}
func peerInfoToPeer(info *p2p.PeerInfo) *proto.Peer {
return &proto.Peer{
Id: info.ID,
Enode: info.Enode,
Enr: info.ENR,
Caps: info.Caps,
Name: info.Name,
Trusted: info.Network.Trusted,
Static: info.Network.Static,
}
}
func (s *Server) ChainSetHead(ctx context.Context, req *proto.ChainSetHeadRequest) (*proto.ChainSetHeadResponse, error) {
s.backend.APIBackend.SetHead(req.Number)
return &proto.ChainSetHeadResponse{}, nil
}

View file

@ -151,8 +151,10 @@ func newFreezer(datadir string, namespace string, readonly bool, maxTableSize ui
// This way they don't have to sync again from block 0 and still be compatible
// for block logs for future blocks. Note that already synced nodes
// won't have past block logs. Newly synced node will have all the data.
if err := freezer.tables[freezerBorReceiptTable].Fill(freezer.tables[freezerHeaderTable].items); err != nil {
return nil, err
if _, ok := freezer.tables[freezerBorReceiptTable]; ok {
if err := freezer.tables[freezerBorReceiptTable].Fill(freezer.tables[freezerHeaderTable].items); err != nil {
return nil, err
}
}
// Truncate all tables to common length.

View file

@ -53,6 +53,7 @@ func TestStateProcessorErrors(t *testing.T) {
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
Ethash: new(params.EthashConfig),
Bor: &params.BorConfig{BurntContract: map[string]string{"0": "0x000000000000000000000000000000000000dead"}},
}
signer = types.LatestSigner(config)
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")

View file

@ -15,4 +15,20 @@
- [```account import```](./account_import.md)
- [```chain```](./chain.md)
- [```chain sethead```](./chain_sethead.md)
- [```peers```](./peers.md)
- [```peers add```](./peers_add.md)
- [```peers list```](./peers_list.md)
- [```peers remove```](./peers_remove.md)
- [```peers status```](./peers_status.md)
- [```status```](./status.md)
- [```version```](./version.md)

6
docs/cli/chain.md Normal file
View file

@ -0,0 +1,6 @@
# Chain
The ```chain``` command groups actions to interact with the blockchain in the client:
- [```chain sethead```](./chain_sethead.md): Set the current chain to a certain block.

12
docs/cli/chain_sethead.md Normal file
View file

@ -0,0 +1,12 @@
# Chain sethead
The ```chain sethead <number>``` command sets the current chain to a certain block.
## Arguments
- ```number```: The block number to roll back.
## Options
- ```yes```: Force set head.

12
docs/cli/peers.md Normal file
View file

@ -0,0 +1,12 @@
# Peers
The ```peers``` command groups actions to interact with peers:
- [```peers add```](./peers_add.md): Joins the local client to another remote peer.
- [```peers list```](./peers_list.md): Lists the connected peers to the Bor client.
- [```peers remove```](./peers_remove.md): Disconnects the local client from a connected peer if exists.
- [```peers status```](./peers_status.md): Display the status of a peer by its id.

8
docs/cli/peers_add.md Normal file
View file

@ -0,0 +1,8 @@
# 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.

4
docs/cli/peers_list.md Normal file
View file

@ -0,0 +1,4 @@
# Peers list
The ```peers list``` command lists the connected peers.

4
docs/cli/peers_remove.md Normal file
View file

@ -0,0 +1,4 @@
# Peers remove
The ```peers remove <enode>``` command disconnects the local client from a connected peer if exists.

4
docs/cli/peers_status.md Normal file
View file

@ -0,0 +1,4 @@
# Peers status
The ```peers status <peer id>``` command displays the status of a peer by its id.

4
docs/cli/status.md Normal file
View file

@ -0,0 +1,4 @@
# Status
The ```status``` command outputs the status of the client.

View file

@ -110,6 +110,8 @@ func generateTestChainWithFork(n int, fork int) (*core.Genesis, []*types.Block,
*/
func TestEth2AssembleBlock(t *testing.T) {
t.Skip("bor due to burn contract")
genesis, blocks := generateTestChain()
n, ethservice := startEthService(t, genesis, blocks[1:9])
defer n.Close()
@ -137,6 +139,8 @@ func TestEth2AssembleBlock(t *testing.T) {
}
func TestEth2AssembleBlockWithAnotherBlocksTxs(t *testing.T) {
t.Skip("bor due to burn contract")
genesis, blocks := generateTestChain()
n, ethservice := startEthService(t, genesis, blocks[1:9])
defer n.Close()

View file

@ -229,7 +229,9 @@ func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, et
return clique.New(chainConfig.Clique, db)
}
// 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)
}
// Otherwise assume proof-of-work

View file

@ -40,7 +40,8 @@ import (
)
var (
deadline = 5 * time.Minute
deadline = 5 * time.Minute
borLogs bool = true
)
type testBackend struct {
@ -174,7 +175,7 @@ func TestBlockSubscription(t *testing.T) {
var (
db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline, false)
api = NewPublicFilterAPI(backend, false, deadline, borLogs)
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) {})
chainEvents = []core.ChainEvent{}
@ -226,7 +227,7 @@ func TestPendingTxFilter(t *testing.T) {
var (
db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline, false)
api = NewPublicFilterAPI(backend, false, deadline, borLogs)
transactions = []*types.Transaction{
types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
@ -281,7 +282,7 @@ func TestLogFilterCreation(t *testing.T) {
var (
db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline, false)
api = NewPublicFilterAPI(backend, false, deadline, borLogs)
testCases = []struct {
crit FilterCriteria
@ -325,7 +326,7 @@ func TestInvalidLogFilterCreation(t *testing.T) {
var (
db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline, false)
api = NewPublicFilterAPI(backend, false, deadline, borLogs)
)
// different situations where log filter creation should fail.
@ -347,7 +348,7 @@ func TestInvalidGetLogsRequest(t *testing.T) {
var (
db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline, false)
api = NewPublicFilterAPI(backend, false, deadline, borLogs)
blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
)
@ -372,7 +373,7 @@ func TestLogFilter(t *testing.T) {
var (
db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline, false)
api = NewPublicFilterAPI(backend, false, deadline, borLogs)
firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222")
@ -486,7 +487,7 @@ func TestPendingLogsSubscription(t *testing.T) {
var (
db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, deadline, false)
api = NewPublicFilterAPI(backend, false, deadline, borLogs)
firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222")
@ -670,7 +671,7 @@ func TestPendingTxFilterDeadlock(t *testing.T) {
var (
db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db}
api = NewPublicFilterAPI(backend, false, timeout, false)
api = NewPublicFilterAPI(backend, false, timeout, borLogs)
done = make(chan struct{})
)

View file

@ -35,7 +35,7 @@ import (
const sampleNumber = 3 // Number of transactions sampled in a block
var (
DefaultMaxPrice = big.NewInt(500 * params.GWei)
DefaultMaxPrice = big.NewInt(5000 * params.GWei)
DefaultIgnorePrice = big.NewInt(2 * params.Wei)
)

View file

@ -234,6 +234,8 @@ func generateTestChain() (*core.Genesis, []*types.Block) {
}
func TestEthClient(t *testing.T) {
t.Skip("bor due to burn contract")
backend, chain := newTestBackend(t)
client, _ := backend.Attach()
defer backend.Close()

View file

@ -89,6 +89,8 @@ func generateTestChain() (*core.Genesis, []*types.Block) {
}
func TestGethClient(t *testing.T) {
t.Skip("bor due to burn contract")
backend, _ := newTestBackend(t)
client, err := backend.Attach()
if err != nil {

1
go.mod
View file

@ -53,6 +53,7 @@ require (
github.com/mattn/go-colorable v0.1.8
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/toml v0.1.2-0.20170918210437-9fafd6967416

3
go.sum
View file

@ -375,6 +375,8 @@ github.com/mitchellh/cli v1.1.2 h1:PvH+lL2B7IQ101xQL63Of8yFS2y+aDlsFcsqNc+u/Kw=
github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-grpc-net-conn v0.0.0-20200427190222-eb030e4876f0 h1:oZuel4h7224ILBLg2SlTxdaMYXDyqcVfL4Cg1PJQHZs=
github.com/mitchellh/go-grpc-net-conn v0.0.0-20200427190222-eb030e4876f0/go.mod h1:ZCzL0JMR6qfm7VrDC8HGwVtPA8D2Ijc/edUSBw58x94=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
@ -732,6 +734,7 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=

View file

@ -1,4 +1,4 @@
package main
package cli
import "github.com/mitchellh/cli"

View file

@ -1,11 +1,11 @@
package main
package cli
import (
"fmt"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/command/flagset"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
)
type AccountImportCommand struct {

View file

@ -1,10 +1,10 @@
package main
package cli
import (
"fmt"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/command/flagset"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
)
type AccountListCommand struct {

View file

@ -1,9 +1,9 @@
package main
package cli
import (
"fmt"
"github.com/ethereum/go-ethereum/command/flagset"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
)
type AccountNewCommand struct {

View file

@ -1,4 +1,4 @@
package main
package cli
import (
"github.com/mitchellh/cli"

View file

@ -1,12 +1,12 @@
package main
package cli
import (
"context"
"fmt"
"strconv"
"github.com/ethereum/go-ethereum/command/flagset"
"github.com/ethereum/go-ethereum/command/server/proto"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
)
// ChainSetHeadCommand is the command to group the peers commands

View file

@ -1,23 +1,19 @@
package main
package cli
import (
"fmt"
"os"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/command/flagset"
"github.com/ethereum/go-ethereum/command/server"
"github.com/ethereum/go-ethereum/command/server/proto"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
"github.com/ethereum/go-ethereum/internal/cli/server"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
"github.com/ethereum/go-ethereum/node"
"github.com/mitchellh/cli"
"github.com/ryanuber/columnize"
"google.golang.org/grpc"
)
func main() {
os.Exit(Run(os.Args[1:]))
}
func Run(args []string) int {
commands := commands()
@ -119,6 +115,11 @@ func commands() map[string]cli.CommandFactory {
Meta2: meta2,
}, nil
},
"status": func() (cli.Command, error) {
return &StatusCommand{
Meta2: meta2,
}, nil
},
}
}

View file

@ -1,4 +1,4 @@
package main
package cli
// Based on https://github.com/hashicorp/nomad/blob/main/command/operator_debug.go
@ -6,7 +6,6 @@ import (
"archive/tar"
"compress/gzip"
"context"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
@ -17,8 +16,12 @@ import (
"syscall"
"time"
"github.com/ethereum/go-ethereum/command/flagset"
"github.com/ethereum/go-ethereum/command/server/proto"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
"github.com/golang/protobuf/jsonpb"
gproto "github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/empty"
grpc_net_conn "github.com/mitchellh/go-grpc-net-conn"
)
type DebugCommand struct {
@ -118,16 +121,35 @@ func (d *DebugCommand) Run(args []string) int {
req.Type = proto.PprofRequest_LOOKUP
req.Profile = profile
}
resp, err := clt.Pprof(ctx, req)
stream, err := clt.Pprof(ctx, req)
if err != nil {
return err
}
// write file
raw, err := hex.DecodeString(resp.Payload)
// wait for open request
msg, err := stream.Recv()
if err != nil {
return err
}
if err := ioutil.WriteFile(filepath.Join(tmp, filename+".prof"), raw, 0755); err != nil {
if _, ok := msg.Event.(*proto.PprofResponse_Open_); !ok {
return fmt.Errorf("expected open message")
}
// create the stream
conn := &grpc_net_conn.Conn{
Stream: stream,
Response: &proto.PprofResponse_Input{},
Decode: grpc_net_conn.SimpleDecoder(func(msg gproto.Message) *[]byte {
return &msg.(*proto.PprofResponse_Input).Data
}),
}
file, err := os.OpenFile(filepath.Join(tmp, filename+".prof"), os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return err
}
defer file.Close()
if _, err := io.Copy(file, conn); err != nil {
return err
}
return nil
@ -148,6 +170,25 @@ func (d *DebugCommand) Run(args []string) int {
}
}
// append the status
{
statusResp, err := clt.Status(ctx, &empty.Empty{})
if err != nil {
d.UI.Output(fmt.Sprintf("Failed to get status: %v", err))
return 1
}
m := jsonpb.Marshaler{}
data, err := m.MarshalToString(statusResp)
if err != nil {
d.UI.Output(err.Error())
return 1
}
if err := ioutil.WriteFile(filepath.Join(tmp, "status.json"), []byte(data), 0644); err != nil {
d.UI.Output(fmt.Sprintf("Failed to write status: %v", err))
return 1
}
}
// Exit before archive if output directory was specified
if d.output != "" {
d.UI.Output(fmt.Sprintf("Created debug directory: %s", tmp))

View file

@ -1,4 +1,4 @@
package main
package cli
import (
"github.com/mitchellh/cli"
@ -17,11 +17,11 @@ func (c *PeersCommand) Help() string {
List the connected peers:
$ bor account new
$ bor peers list
Add a new peer by enode:
$ bor account import
$ bor peers add <enode>
Remove a connected peer by enode:

View file

@ -1,10 +1,10 @@
package main
package cli
import (
"context"
"github.com/ethereum/go-ethereum/command/flagset"
"github.com/ethereum/go-ethereum/command/server/proto"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
)
// PeersAddCommand is the command to group the peers commands

View file

@ -1,12 +1,12 @@
package main
package cli
import (
"context"
"fmt"
"strings"
"github.com/ethereum/go-ethereum/command/flagset"
"github.com/ethereum/go-ethereum/command/server/proto"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
)
// PeersListCommand is the command to group the peers commands
@ -18,7 +18,7 @@ type PeersListCommand struct {
func (p *PeersListCommand) Help() string {
return `Usage: bor peers list
Build an archive containing Bor pprof traces
Lists the connected peers
` + p.Flags().Help()
}

View file

@ -1,10 +1,10 @@
package main
package cli
import (
"context"
"github.com/ethereum/go-ethereum/command/flagset"
"github.com/ethereum/go-ethereum/command/server/proto"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
)
// PeersRemoveCommand is the command to group the peers commands

View file

@ -1,12 +1,12 @@
package main
package cli
import (
"context"
"fmt"
"strings"
"github.com/ethereum/go-ethereum/command/flagset"
"github.com/ethereum/go-ethereum/command/server/proto"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
)
// PeersStatusCommand is the command to group the peers commands

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -14,12 +14,12 @@ import (
godebug "runtime/debug"
"github.com/ethereum/go-ethereum/command/server/chains"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/fdlimit"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/eth/gasprice"
"github.com/ethereum/go-ethereum/internal/cli/server/chains"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"

View file

@ -1,7 +1,7 @@
package server
import (
"github.com/ethereum/go-ethereum/command/flagset"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
)
func (c *Command) Flags() *flagset.Flagset {

File diff suppressed because it is too large Load diff

View file

@ -2,10 +2,12 @@ syntax = "proto3";
package proto;
import "google/protobuf/empty.proto";
option go_package = "/command/server/proto";
service Bor {
rpc Pprof(PprofRequest) returns (PprofResponse);
rpc Pprof(PprofRequest) returns (stream PprofResponse);
rpc PeersAdd(PeersAddRequest) returns (PeersAddResponse);
@ -16,6 +18,8 @@ service Bor {
rpc PeersStatus(PeersStatusRequest) returns (PeersStatusResponse);
rpc ChainSetHead(ChainSetHeadRequest) returns (ChainSetHeadResponse);
rpc Status(google.protobuf.Empty) returns (StatusResponse);
}
@ -67,6 +71,32 @@ message ChainSetHeadRequest {
message ChainSetHeadResponse {
}
message StatusResponse {
Header currentBlock = 1;
Header currentHeader = 2;
int64 numPeers = 3;
string syncMode = 4;
Syncing syncing = 5;
repeated Fork forks = 6;
message Fork {
string name = 1;
int64 block = 2;
bool disabled = 3;
}
message Syncing {
int64 startingBlock = 1;
int64 highestBlock = 2;
int64 currentBlock = 3;
}
}
message Header {
string hash = 1;
uint64 number = 2;
}
message PprofRequest {
Type type = 1;
@ -82,6 +112,18 @@ message PprofRequest {
}
message PprofResponse {
string payload = 1;
map<string, string> headers = 2;
oneof event {
Open open = 1;
Input input = 2;
google.protobuf.Empty eof = 3;
}
message Open {
map<string, string> headers = 1;
int64 size = 2;
}
message Input {
bytes data = 1;
}
}

View file

@ -4,6 +4,7 @@ package proto
import (
context "context"
empty "github.com/golang/protobuf/ptypes/empty"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
@ -18,12 +19,13 @@ const _ = grpc.SupportPackageIsVersion7
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type BorClient interface {
Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (*PprofResponse, error)
Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (Bor_PprofClient, error)
PeersAdd(ctx context.Context, in *PeersAddRequest, opts ...grpc.CallOption) (*PeersAddResponse, error)
PeersRemove(ctx context.Context, in *PeersRemoveRequest, opts ...grpc.CallOption) (*PeersRemoveResponse, error)
PeersList(ctx context.Context, in *PeersListRequest, opts ...grpc.CallOption) (*PeersListResponse, error)
PeersStatus(ctx context.Context, in *PeersStatusRequest, opts ...grpc.CallOption) (*PeersStatusResponse, error)
ChainSetHead(ctx context.Context, in *ChainSetHeadRequest, opts ...grpc.CallOption) (*ChainSetHeadResponse, error)
Status(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*StatusResponse, error)
}
type borClient struct {
@ -34,13 +36,36 @@ func NewBorClient(cc grpc.ClientConnInterface) BorClient {
return &borClient{cc}
}
func (c *borClient) Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (*PprofResponse, error) {
out := new(PprofResponse)
err := c.cc.Invoke(ctx, "/proto.Bor/Pprof", in, out, opts...)
func (c *borClient) Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (Bor_PprofClient, error) {
stream, err := c.cc.NewStream(ctx, &Bor_ServiceDesc.Streams[0], "/proto.Bor/Pprof", opts...)
if err != nil {
return nil, err
}
return out, nil
x := &borPprofClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type Bor_PprofClient interface {
Recv() (*PprofResponse, error)
grpc.ClientStream
}
type borPprofClient struct {
grpc.ClientStream
}
func (x *borPprofClient) Recv() (*PprofResponse, error) {
m := new(PprofResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *borClient) PeersAdd(ctx context.Context, in *PeersAddRequest, opts ...grpc.CallOption) (*PeersAddResponse, error) {
@ -88,16 +113,26 @@ func (c *borClient) ChainSetHead(ctx context.Context, in *ChainSetHeadRequest, o
return out, nil
}
func (c *borClient) Status(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*StatusResponse, error) {
out := new(StatusResponse)
err := c.cc.Invoke(ctx, "/proto.Bor/Status", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// BorServer is the server API for Bor service.
// All implementations must embed UnimplementedBorServer
// for forward compatibility
type BorServer interface {
Pprof(context.Context, *PprofRequest) (*PprofResponse, error)
Pprof(*PprofRequest, Bor_PprofServer) error
PeersAdd(context.Context, *PeersAddRequest) (*PeersAddResponse, error)
PeersRemove(context.Context, *PeersRemoveRequest) (*PeersRemoveResponse, error)
PeersList(context.Context, *PeersListRequest) (*PeersListResponse, error)
PeersStatus(context.Context, *PeersStatusRequest) (*PeersStatusResponse, error)
ChainSetHead(context.Context, *ChainSetHeadRequest) (*ChainSetHeadResponse, error)
Status(context.Context, *empty.Empty) (*StatusResponse, error)
mustEmbedUnimplementedBorServer()
}
@ -105,8 +140,8 @@ type BorServer interface {
type UnimplementedBorServer struct {
}
func (UnimplementedBorServer) Pprof(context.Context, *PprofRequest) (*PprofResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Pprof not implemented")
func (UnimplementedBorServer) Pprof(*PprofRequest, Bor_PprofServer) error {
return status.Errorf(codes.Unimplemented, "method Pprof not implemented")
}
func (UnimplementedBorServer) PeersAdd(context.Context, *PeersAddRequest) (*PeersAddResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method PeersAdd not implemented")
@ -123,6 +158,9 @@ func (UnimplementedBorServer) PeersStatus(context.Context, *PeersStatusRequest)
func (UnimplementedBorServer) ChainSetHead(context.Context, *ChainSetHeadRequest) (*ChainSetHeadResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ChainSetHead not implemented")
}
func (UnimplementedBorServer) Status(context.Context, *empty.Empty) (*StatusResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Status not implemented")
}
func (UnimplementedBorServer) mustEmbedUnimplementedBorServer() {}
// UnsafeBorServer may be embedded to opt out of forward compatibility for this service.
@ -136,22 +174,25 @@ func RegisterBorServer(s grpc.ServiceRegistrar, srv BorServer) {
s.RegisterService(&Bor_ServiceDesc, srv)
}
func _Bor_Pprof_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PprofRequest)
if err := dec(in); err != nil {
return nil, err
func _Bor_Pprof_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(PprofRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
if interceptor == nil {
return srv.(BorServer).Pprof(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/proto.Bor/Pprof",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BorServer).Pprof(ctx, req.(*PprofRequest))
}
return interceptor(ctx, in, info, handler)
return srv.(BorServer).Pprof(m, &borPprofServer{stream})
}
type Bor_PprofServer interface {
Send(*PprofResponse) error
grpc.ServerStream
}
type borPprofServer struct {
grpc.ServerStream
}
func (x *borPprofServer) Send(m *PprofResponse) error {
return x.ServerStream.SendMsg(m)
}
func _Bor_PeersAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
@ -244,6 +285,24 @@ func _Bor_ChainSetHead_Handler(srv interface{}, ctx context.Context, dec func(in
return interceptor(ctx, in, info, handler)
}
func _Bor_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(empty.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BorServer).Status(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/proto.Bor/Status",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BorServer).Status(ctx, req.(*empty.Empty))
}
return interceptor(ctx, in, info, handler)
}
// Bor_ServiceDesc is the grpc.ServiceDesc for Bor service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@ -251,10 +310,6 @@ var Bor_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proto.Bor",
HandlerType: (*BorServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Pprof",
Handler: _Bor_Pprof_Handler,
},
{
MethodName: "PeersAdd",
Handler: _Bor_PeersAdd_Handler,
@ -275,7 +330,17 @@ var Bor_ServiceDesc = grpc.ServiceDesc{
MethodName: "ChainSetHead",
Handler: _Bor_ChainSetHead_Handler,
},
{
MethodName: "Status",
Handler: _Bor_Status_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "Pprof",
Handler: _Bor_Pprof_Handler,
ServerStreams: true,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "command/server/proto/server.proto",
}

View file

@ -11,11 +11,11 @@ import (
"time"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/command/server/proto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/ethstats"
"github.com/ethereum/go-ethereum/graphql"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/metrics/influxdb"
@ -38,10 +38,13 @@ type Server struct {
backend *eth.Ethereum
grpcServer *grpc.Server
tracer *sdktrace.TracerProvider
config *Config
}
func NewServer(config *Config) (*Server, error) {
srv := &Server{}
srv := &Server{
config: config,
}
// start the logger
setupLogger(config.LogLevel)

View file

@ -0,0 +1,220 @@
package server
import (
"context"
"fmt"
"math/big"
"reflect"
"strings"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/internal/cli/server/pprof"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
gproto "github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/empty"
grpc_net_conn "github.com/mitchellh/go-grpc-net-conn"
)
func (s *Server) Pprof(req *proto.PprofRequest, stream proto.Bor_PprofServer) error {
var payload []byte
var headers map[string]string
var err error
ctx := context.Background()
switch req.Type {
case proto.PprofRequest_CPU:
payload, headers, err = pprof.CPUProfile(ctx, int(req.Seconds))
case proto.PprofRequest_TRACE:
payload, headers, err = pprof.Trace(ctx, int(req.Seconds))
case proto.PprofRequest_LOOKUP:
payload, headers, err = pprof.Profile(req.Profile, 0, 0)
}
if err != nil {
return err
}
// open the stream and send the headers
err = stream.Send(&proto.PprofResponse{
Event: &proto.PprofResponse_Open_{
Open: &proto.PprofResponse_Open{
Headers: headers,
Size: int64(len(payload)),
},
},
})
if err != nil {
return err
}
// Wrap our conn around the response.
conn := &grpc_net_conn.Conn{
Stream: stream,
Request: &proto.PprofResponse_Input{},
Encode: grpc_net_conn.SimpleEncoder(func(msg gproto.Message) *[]byte {
return &msg.(*proto.PprofResponse_Input).Data
}),
}
if _, err := conn.Write(payload); err != nil {
return err
}
// send the eof
err = stream.Send(&proto.PprofResponse{
Event: &proto.PprofResponse_Eof{},
})
if err != nil {
return err
}
return nil
}
func (s *Server) PeersAdd(ctx context.Context, req *proto.PeersAddRequest) (*proto.PeersAddResponse, error) {
node, err := enode.Parse(enode.ValidSchemes, req.Enode)
if err != nil {
return nil, fmt.Errorf("invalid enode: %v", err)
}
srv := s.node.Server()
if req.Trusted {
srv.AddTrustedPeer(node)
} else {
srv.AddPeer(node)
}
return &proto.PeersAddResponse{}, nil
}
func (s *Server) PeersRemove(ctx context.Context, req *proto.PeersRemoveRequest) (*proto.PeersRemoveResponse, error) {
node, err := enode.Parse(enode.ValidSchemes, req.Enode)
if err != nil {
return nil, fmt.Errorf("invalid enode: %v", err)
}
srv := s.node.Server()
if req.Trusted {
srv.RemoveTrustedPeer(node)
} else {
srv.RemovePeer(node)
}
return &proto.PeersRemoveResponse{}, nil
}
func (s *Server) PeersList(ctx context.Context, req *proto.PeersListRequest) (*proto.PeersListResponse, error) {
resp := &proto.PeersListResponse{}
peers := s.node.Server().PeersInfo()
for _, p := range peers {
resp.Peers = append(resp.Peers, peerInfoToPeer(p))
}
return resp, nil
}
func (s *Server) PeersStatus(ctx context.Context, req *proto.PeersStatusRequest) (*proto.PeersStatusResponse, error) {
var peerInfo *p2p.PeerInfo
for _, p := range s.node.Server().PeersInfo() {
if strings.HasPrefix(p.ID, req.Enode) {
if peerInfo != nil {
return nil, fmt.Errorf("more than one peer with the same prefix")
}
peerInfo = p
}
}
resp := &proto.PeersStatusResponse{}
if peerInfo != nil {
resp.Peer = peerInfoToPeer(peerInfo)
}
return resp, nil
}
func peerInfoToPeer(info *p2p.PeerInfo) *proto.Peer {
return &proto.Peer{
Id: info.ID,
Enode: info.Enode,
Enr: info.ENR,
Caps: info.Caps,
Name: info.Name,
Trusted: info.Network.Trusted,
Static: info.Network.Static,
}
}
func (s *Server) ChainSetHead(ctx context.Context, req *proto.ChainSetHeadRequest) (*proto.ChainSetHeadResponse, error) {
s.backend.APIBackend.SetHead(req.Number)
return &proto.ChainSetHeadResponse{}, nil
}
func (s *Server) Status(ctx context.Context, _ *empty.Empty) (*proto.StatusResponse, error) {
apiBackend := s.backend.APIBackend
syncProgress := apiBackend.SyncProgress()
resp := &proto.StatusResponse{
CurrentHeader: headerToProtoHeader(apiBackend.CurrentHeader()),
CurrentBlock: headerToProtoHeader(apiBackend.CurrentBlock().Header()),
NumPeers: int64(len(s.node.Server().PeersInfo())),
SyncMode: s.config.SyncMode,
Syncing: &proto.StatusResponse_Syncing{
StartingBlock: int64(syncProgress.StartingBlock),
HighestBlock: int64(syncProgress.HighestBlock),
CurrentBlock: int64(syncProgress.CurrentBlock),
},
Forks: gatherForks(s.config.chain.Genesis.Config, s.config.chain.Genesis.Config.Bor),
}
return resp, nil
}
func headerToProtoHeader(h *types.Header) *proto.Header {
return &proto.Header{
Hash: h.Hash().String(),
Number: h.Number.Uint64(),
}
}
var bigIntT = reflect.TypeOf(new(big.Int)).Kind()
// gatherForks gathers all the fork numbers via reflection
func gatherForks(configList ...interface{}) []*proto.StatusResponse_Fork {
var forks []*proto.StatusResponse_Fork
for _, config := range configList {
kind := reflect.TypeOf(config)
for kind.Kind() == reflect.Ptr {
kind = kind.Elem()
}
skip := "DAOForkBlock"
conf := reflect.ValueOf(config).Elem()
for i := 0; i < kind.NumField(); i++ {
// Fetch the next field and skip non-fork rules
field := kind.Field(i)
if strings.Contains(field.Name, skip) {
continue
}
if !strings.HasSuffix(field.Name, "Block") {
continue
}
fork := &proto.StatusResponse_Fork{
Name: strings.TrimSuffix(field.Name, "Block"),
}
val := conf.Field(i)
switch field.Type.Kind() {
case bigIntT:
rule := val.Interface().(*big.Int)
if rule != nil {
fork.Block = rule.Int64()
} else {
fork.Disabled = true
}
case reflect.Uint64:
fork.Block = int64(val.Uint())
default:
continue
}
forks = append(forks, fork)
}
}
return forks
}

View file

@ -0,0 +1,43 @@
package server
import (
"math/big"
"testing"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
"github.com/stretchr/testify/assert"
)
func TestGatherBlocks(t *testing.T) {
type c struct {
ABlock *big.Int
BBlock *big.Int
}
type d struct {
DBlock uint64
}
val := &c{
BBlock: new(big.Int).SetInt64(1),
}
val2 := &d{
DBlock: 10,
}
expect := []*proto.StatusResponse_Fork{
{
Name: "A",
Disabled: true,
},
{
Name: "B",
Block: 1,
},
{
Name: "D",
Block: 10,
},
}
res := gatherForks(val, val2)
assert.Equal(t, res, expect)
}

87
internal/cli/status.go Normal file
View file

@ -0,0 +1,87 @@
package cli
import (
"context"
"fmt"
"strings"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
"github.com/golang/protobuf/ptypes/empty"
)
// StatusCommand is the command to output the status of the client
type StatusCommand struct {
*Meta2
}
// Help implements the cli.Command interface
func (p *StatusCommand) Help() string {
return `Usage: bor status
Output the status of the client`
}
// Synopsis implements the cli.Command interface
func (c *StatusCommand) Synopsis() string {
return "Output the status of the client"
}
// Run implements the cli.Command interface
func (c *StatusCommand) Run(args []string) int {
flags := c.NewFlagSet("status")
if err := flags.Parse(args); err != nil {
c.UI.Error(err.Error())
return 1
}
borClt, err := c.BorConn()
if err != nil {
c.UI.Error(err.Error())
return 1
}
status, err := borClt.Status(context.Background(), &empty.Empty{})
if err != nil {
c.UI.Error(err.Error())
return 1
}
c.UI.Output(printStatus(status))
return 0
}
func printStatus(status *proto.StatusResponse) string {
printHeader := func(h *proto.Header) string {
return formatKV([]string{
fmt.Sprintf("Hash|%s", h.Hash),
fmt.Sprintf("Number|%d", h.Number),
})
}
forks := make([]string, len(status.Forks)+1)
forks[0] = "Name|Block|Enabled"
for i, d := range status.Forks {
forks[i+1] = fmt.Sprintf("%s|%d|%v", d.Name, d.Block, !d.Disabled)
}
full := []string{
"General",
formatKV([]string{
fmt.Sprintf("Num peers|%d", status.NumPeers),
fmt.Sprintf("Sync mode|%s", status.SyncMode),
}),
"\nCurrent Header",
printHeader(status.CurrentHeader),
"\nCurrent Block",
printHeader(status.CurrentBlock),
"\nSyncing",
formatKV([]string{
fmt.Sprintf("Current block|%d", status.Syncing.CurrentBlock),
fmt.Sprintf("Highest block|%d", status.Syncing.HighestBlock),
fmt.Sprintf("Starting block|%d", status.Syncing.StartingBlock),
}),
"\nForks",
formatList(forks),
}
return strings.Join(full, "\n")
}

View file

@ -1,4 +1,4 @@
package main
package cli
import (
"github.com/ethereum/go-ethereum/params"

View file

@ -634,7 +634,7 @@ func (s *PublicBlockChainAPI) GetTransactionReceiptsByBlock(ctx context.Context,
}
if len(txs) != len(receipts) {
return nil, fmt.Errorf("txs length doesn't equal to receipts' length", len(txs), len(receipts))
return nil, fmt.Errorf("txs length %d doesn't equal to receipts' length %d", len(txs), len(receipts))
}
txReceipts := make([]map[string]interface{}, 0, len(txs))

View file

@ -155,6 +155,8 @@ public class AndroidTest extends InstrumentationTestCase {
//
// This method has been adapted from golang.org/x/mobile/bind/java/seq_test.go/runTest
func TestAndroid(t *testing.T) {
t.Skip("Bor: We do not test this")
// Skip tests on Windows altogether
if runtime.GOOS == "windows" {
t.Skip("cannot test Android bindings on Windows, skipping")

View file

@ -360,16 +360,16 @@ var (
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil}
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, &BorConfig{BurntContract: map[string]string{"0": "0x000000000000000000000000000000000000dead"}}}
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Clique consensus.
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, &BorConfig{BurntContract: map[string]string{"0": "0x000000000000000000000000000000000000dead"}}}
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil}
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, &BorConfig{BurntContract: map[string]string{"0": "0x000000000000000000000000000000000000dead"}}}
TestRules = TestChainConfig.Rules(new(big.Int))
)

15
scripts/tools-protobuf.sh Normal file → Executable file
View file

@ -1,5 +1,16 @@
curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v3.12.0/protoc-3.12.0-linux-x86_64.zip
sudo unzip protoc-3.12.0-linux-x86_64.zip -d /usr/local/bin
#!/bin/bash
# Install protobuf
PROTOC_ZIP=protoc-3.12.0-linux-x86_64.zip
curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.12.0/$PROTOC_ZIP
sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
sudo unzip -o $PROTOC_ZIP -d /usr/local 'include/*'
rm -f $PROTOC_ZIP
# Change permissions to use the binary
sudo chmod 755 -R /usr/local/bin/protoc
sudo chmod 755 -R /usr/local/include
# Install golang extensions (DO NOT CHANGE THE VERSIONS)
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.25.0
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1

@ -1 +0,0 @@
Subproject commit 092a8834dc445e683103689d6f0e75a5d380a190