mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
cmd/geth, miner: Added HTTP push notifications for new work packages
This commit is contained in:
parent
7abedf9bbb
commit
faabfa8955
6 changed files with 138 additions and 0 deletions
|
|
@ -122,6 +122,7 @@ var (
|
||||||
utils.GpoBlocksFlag,
|
utils.GpoBlocksFlag,
|
||||||
utils.GpoPercentileFlag,
|
utils.GpoPercentileFlag,
|
||||||
utils.ExtraDataFlag,
|
utils.ExtraDataFlag,
|
||||||
|
utils.NotifyWorkFlag,
|
||||||
configFileFlag,
|
configFileFlag,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,7 @@ var AppHelpFlagGroups = []flagGroup{
|
||||||
utils.TargetGasLimitFlag,
|
utils.TargetGasLimitFlag,
|
||||||
utils.GasPriceFlag,
|
utils.GasPriceFlag,
|
||||||
utils.ExtraDataFlag,
|
utils.ExtraDataFlag,
|
||||||
|
utils.NotifyWorkFlag,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -341,6 +341,10 @@ var (
|
||||||
Name: "extradata",
|
Name: "extradata",
|
||||||
Usage: "Block extra data set by the miner (default = client version)",
|
Usage: "Block extra data set by the miner (default = client version)",
|
||||||
}
|
}
|
||||||
|
NotifyWorkFlag = cli.StringFlag{
|
||||||
|
Name: "notifywork",
|
||||||
|
Usage: "URLs to which work package notifications are pushed. URLS should be a comma-delimited list of HTTP URLs.",
|
||||||
|
}
|
||||||
// Account settings
|
// Account settings
|
||||||
UnlockedAccountFlag = cli.StringFlag{
|
UnlockedAccountFlag = cli.StringFlag{
|
||||||
Name: "unlock",
|
Name: "unlock",
|
||||||
|
|
@ -1100,6 +1104,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
|
||||||
if ctx.GlobalIsSet(ExtraDataFlag.Name) {
|
if ctx.GlobalIsSet(ExtraDataFlag.Name) {
|
||||||
cfg.ExtraData = []byte(ctx.GlobalString(ExtraDataFlag.Name))
|
cfg.ExtraData = []byte(ctx.GlobalString(ExtraDataFlag.Name))
|
||||||
}
|
}
|
||||||
|
if ctx.GlobalIsSet(NotifyWorkFlag.Name) {
|
||||||
|
cfg.NotifyWork = ctx.GlobalString(NotifyWorkFlag.Name)
|
||||||
|
}
|
||||||
if ctx.GlobalIsSet(GasPriceFlag.Name) {
|
if ctx.GlobalIsSet(GasPriceFlag.Name) {
|
||||||
cfg.GasPrice = GlobalBig(ctx, GasPriceFlag.Name)
|
cfg.GasPrice = GlobalBig(ctx, GasPriceFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,11 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine)
|
eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine)
|
||||||
eth.miner.SetExtra(makeExtraData(config.ExtraData))
|
eth.miner.SetExtra(makeExtraData(config.ExtraData))
|
||||||
|
|
||||||
|
// Set up mining work push notifications if requested
|
||||||
|
if len(config.NotifyWork) > 0 {
|
||||||
|
eth.miner.Register(miner.NewNotificationAgent(eth.blockchain, eth.engine, config.NotifyWork))
|
||||||
|
}
|
||||||
|
|
||||||
eth.APIBackend = &EthAPIBackend{eth, nil}
|
eth.APIBackend = &EthAPIBackend{eth, nil}
|
||||||
gpoParams := config.GPO
|
gpoParams := config.GPO
|
||||||
if gpoParams.Default == nil {
|
if gpoParams.Default == nil {
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,7 @@ type Config struct {
|
||||||
Etherbase common.Address `toml:",omitempty"`
|
Etherbase common.Address `toml:",omitempty"`
|
||||||
MinerThreads int `toml:",omitempty"`
|
MinerThreads int `toml:",omitempty"`
|
||||||
ExtraData []byte `toml:",omitempty"`
|
ExtraData []byte `toml:",omitempty"`
|
||||||
|
NotifyWork string `toml:",omitempty"`
|
||||||
GasPrice *big.Int
|
GasPrice *big.Int
|
||||||
|
|
||||||
// Ethash options
|
// Ethash options
|
||||||
|
|
|
||||||
123
miner/notification_agent.go
Normal file
123
miner/notification_agent.go
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
// Copyright 2015 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 miner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"math/big"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The notification agent pushes new work packages to a preset list of HTTP endpoints
|
||||||
|
type NotificationAgent struct {
|
||||||
|
wg sync.WaitGroup
|
||||||
|
workCh chan *Work
|
||||||
|
stop chan struct{}
|
||||||
|
returnCh chan<- *Result
|
||||||
|
targets []string
|
||||||
|
client *http.Client
|
||||||
|
|
||||||
|
chain consensus.ChainReader
|
||||||
|
engine consensus.Engine
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNotificationAgent(chain consensus.ChainReader, engine consensus.Engine, targets string) *NotificationAgent {
|
||||||
|
miner := &NotificationAgent{
|
||||||
|
chain: chain,
|
||||||
|
engine: engine,
|
||||||
|
stop: make(chan struct{}, 1),
|
||||||
|
workCh: make(chan *Work, 1),
|
||||||
|
targets: strings.Split(targets, ","),
|
||||||
|
client: &http.Client{Timeout: time.Second * 10},
|
||||||
|
}
|
||||||
|
return miner
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *NotificationAgent) Work() chan<- *Work { return self.workCh }
|
||||||
|
func (self *NotificationAgent) SetReturnCh(ch chan<- *Result) { self.returnCh = ch }
|
||||||
|
|
||||||
|
func (self *NotificationAgent) Stop() {
|
||||||
|
self.stop <- struct{}{}
|
||||||
|
done:
|
||||||
|
// Empty work channel
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-self.workCh:
|
||||||
|
default:
|
||||||
|
break done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *NotificationAgent) Start() {
|
||||||
|
go self.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *NotificationAgent) update() {
|
||||||
|
out:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case work := <-self.workCh:
|
||||||
|
var res [3]string
|
||||||
|
|
||||||
|
block := work.Block
|
||||||
|
|
||||||
|
res[0] = block.HashNoNonce().Hex()
|
||||||
|
seedHash := ethash.SeedHash(block.NumberU64())
|
||||||
|
res[1] = common.BytesToHash(seedHash).Hex()
|
||||||
|
// Calculate the "target" to be returned to the external miner
|
||||||
|
n := big.NewInt(1)
|
||||||
|
n.Lsh(n, 255)
|
||||||
|
n.Div(n, block.Difficulty())
|
||||||
|
n.Lsh(n, 1)
|
||||||
|
res[2] = common.BytesToHash(n.Bytes()).Hex()
|
||||||
|
|
||||||
|
resJson, err := json.Marshal(res)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to marshal work package into JSON string")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
self.wg.Add(len(self.targets))
|
||||||
|
for _, target := range self.targets {
|
||||||
|
func(t string) {
|
||||||
|
_, err := self.client.Post(t, "application/json", bytes.NewBuffer(resJson))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Error invoking work notification handler", "handler", t, "err", err)
|
||||||
|
}
|
||||||
|
self.wg.Done()
|
||||||
|
}(target)
|
||||||
|
}
|
||||||
|
self.wg.Wait()
|
||||||
|
case <-self.stop:
|
||||||
|
break out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *NotificationAgent) GetHashRate() int64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue