mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
Merge 919fd902c5 into 98be7cd833
This commit is contained in:
commit
3cce88a0db
13 changed files with 172 additions and 19 deletions
2
Makefile
2
Makefile
|
|
@ -98,7 +98,7 @@ geth-ios: xgo
|
|||
@ls -ld $(GOBIN)/geth-ios-*
|
||||
|
||||
evm:
|
||||
build/env.sh $(GOROOT)/bin/go install -v $(shell build/flags.sh) ./cmd/evm
|
||||
build/env.sh go install -v $(shell build/flags.sh) ./cmd/evm
|
||||
@echo "Done building."
|
||||
@echo "Run \"$(GOBIN)/evm to start the evm."
|
||||
|
||||
|
|
|
|||
|
|
@ -207,6 +207,9 @@ participating.
|
|||
utils.GpobaseStepUpFlag,
|
||||
utils.GpobaseCorrectionFactorFlag,
|
||||
utils.ExtraDataFlag,
|
||||
utils.FixedDifficultyFlag,
|
||||
utils.PollIntervalFlag,
|
||||
utils.MinerPassphraseFlag,
|
||||
}
|
||||
app.Flags = append(app.Flags, debug.Flags...)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,21 +21,21 @@ import "github.com/ethereum/go-ethereum/p2p/discover"
|
|||
// FrontierBootNodes are the enode URLs of the P2P bootstrap nodes running on
|
||||
// the Frontier network.
|
||||
var FrontierBootNodes = []*discover.Node{
|
||||
// ETH/DEV Go Bootnodes
|
||||
discover.MustParseNode("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303"), // IE
|
||||
discover.MustParseNode("enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303"), // BR
|
||||
discover.MustParseNode("enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303"), // SG
|
||||
|
||||
// ETH/DEV Cpp Bootnodes
|
||||
discover.MustParseNode("enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303"),
|
||||
// ETH/DEV Go Bootnodes
|
||||
// discover.MustParseNode("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303"), // IE
|
||||
// discover.MustParseNode("enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303"), // BR
|
||||
// discover.MustParseNode("enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303"), // SG
|
||||
//
|
||||
// // ETH/DEV Cpp Bootnodes
|
||||
// discover.MustParseNode("enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303"),
|
||||
}
|
||||
|
||||
// TestNetBootNodes are the enode URLs of the P2P bootstrap nodes running on the
|
||||
// Morden test network.
|
||||
var TestNetBootNodes = []*discover.Node{
|
||||
// ETH/DEV Go Bootnodes
|
||||
discover.MustParseNode("enode://e4533109cc9bd7604e4ff6c095f7a1d807e15b38e9bfeb05d3b7c423ba86af0a9e89abbf40bd9dde4250fef114cd09270fa4e224cbeef8b7bf05a51e8260d6b8@94.242.229.4:40404"),
|
||||
discover.MustParseNode("enode://8c336ee6f03e99613ad21274f269479bf4413fb294d697ef15ab897598afb931f56beb8e97af530aee20ce2bcba5776f4a312bc168545de4d43736992c814592@94.242.229.203:30303"),
|
||||
// ETH/DEV Go Bootnodes
|
||||
// discover.MustParseNode("enode://e4533109cc9bd7604e4ff6c095f7a1d807e15b38e9bfeb05d3b7c423ba86af0a9e89abbf40bd9dde4250fef114cd09270fa4e224cbeef8b7bf05a51e8260d6b8@94.242.229.4:40404"),
|
||||
// discover.MustParseNode("enode://8c336ee6f03e99613ad21274f269479bf4413fb294d697ef15ab897598afb931f56beb8e97af530aee20ce2bcba5776f4a312bc168545de4d43736992c814592@94.242.229.203:30303"),
|
||||
|
||||
// ETH/DEV Cpp Bootnodes
|
||||
// ETH/DEV Cpp Bootnodes
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,6 +396,21 @@ var (
|
|||
Usage: "Suggested gas price base correction factor (%)",
|
||||
Value: 110,
|
||||
}
|
||||
FixedDifficultyFlag = cli.IntFlag{
|
||||
Name: "difficulty",
|
||||
Usage: "Specify a fixed difficulty.",
|
||||
Value: -1,
|
||||
}
|
||||
PollIntervalFlag = cli.IntFlag{
|
||||
Name: "interval",
|
||||
Usage: "Miner polling interval in milliseconds.",
|
||||
Value: 200,
|
||||
}
|
||||
MinerPassphraseFlag = cli.StringFlag{
|
||||
Name: "minerpass",
|
||||
Usage: "Passphrase used to unlock key for signing blocks.",
|
||||
Value: "",
|
||||
}
|
||||
)
|
||||
|
||||
// MustMakeDataDir retrieves the currently requested data directory, terminating
|
||||
|
|
@ -719,6 +734,9 @@ func MakeSystemNode(name, version string, relconf release.Config, extra []byte,
|
|||
GpobaseCorrectionFactor: ctx.GlobalInt(GpobaseCorrectionFactorFlag.Name),
|
||||
SolcPath: ctx.GlobalString(SolcPathFlag.Name),
|
||||
AutoDAG: ctx.GlobalBool(AutoDAGFlag.Name) || ctx.GlobalBool(MiningEnabledFlag.Name),
|
||||
MinerPassphrase: ctx.GlobalString(MinerPassphraseFlag.Name),
|
||||
FixedDifficulty: ctx.GlobalInt(FixedDifficultyFlag.Name),
|
||||
PollInterval: ctx.GlobalInt(PollIntervalFlag.Name),
|
||||
}
|
||||
// Configure the Whisper service
|
||||
shhEnable := ctx.GlobalBool(WhisperEnabledFlag.Name)
|
||||
|
|
@ -808,7 +826,9 @@ func MustMakeChainConfig(ctx *cli.Context) *core.ChainConfig {
|
|||
db := MakeChainDatabase(ctx)
|
||||
defer db.Close()
|
||||
|
||||
return MustMakeChainConfigFromDb(ctx, db)
|
||||
config := MustMakeChainConfigFromDb(ctx, db)
|
||||
config.FixedDifficulty = ctx.GlobalInt(FixedDifficultyFlag.Name)
|
||||
return config
|
||||
}
|
||||
|
||||
// MustMakeChainConfigFromDb reads the chain configuration from the given database.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
|
|
@ -24,6 +25,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/pow"
|
||||
|
|
@ -200,6 +202,44 @@ func (v *BlockValidator) ValidateHeader(header, parent *types.Header, checkPow b
|
|||
return ValidateHeader(v.config, v.Pow, header, parent, checkPow, false)
|
||||
}
|
||||
|
||||
func ValidateHeaderSignature(header, parent *types.Header) error {
|
||||
if header.Coinbase != parent.Coinbase {
|
||||
return ValidationError("Block signature validation error: coinbase does not match parent.")
|
||||
}
|
||||
|
||||
validator := parent.Coinbase
|
||||
hash := HashOfHashes(header)
|
||||
sig := header.Extra
|
||||
|
||||
if sig == nil || len(sig) == 0 {
|
||||
return ValidationError("Rejecting unsigned block")
|
||||
}
|
||||
|
||||
pub, err := crypto.SigToPub(hash.Bytes(), sig)
|
||||
|
||||
if err != nil {
|
||||
return ValidationError(fmt.Sprintf("Block signature validation error: %s", err))
|
||||
}
|
||||
addr := crypto.PubkeyToAddress(*pub)
|
||||
|
||||
if addr != validator {
|
||||
return ValidationError("Block signature check failed.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func HashOfHashes(header *types.Header) common.Hash {
|
||||
hashes := [][]byte{
|
||||
header.ParentHash.Bytes(),
|
||||
header.UncleHash.Bytes(),
|
||||
header.Root.Bytes(),
|
||||
header.TxHash.Bytes(),
|
||||
header.ReceiptHash.Bytes(),
|
||||
}
|
||||
hash := crypto.Keccak256Hash(bytes.Join(hashes, []byte("")))
|
||||
return hash
|
||||
}
|
||||
|
||||
// Validates a header. Returns an error if the header is invalid.
|
||||
//
|
||||
// See YP section 4.3.4. "Block Header Validity"
|
||||
|
|
@ -208,6 +248,11 @@ func ValidateHeader(config *ChainConfig, pow pow.PoW, header *types.Header, pare
|
|||
return fmt.Errorf("Header extra data too long (%d)", len(header.Extra))
|
||||
}
|
||||
|
||||
sigResult := ValidateHeaderSignature(header, parent)
|
||||
if sigResult != nil {
|
||||
return sigResult
|
||||
}
|
||||
|
||||
if uncle {
|
||||
if header.Time.Cmp(common.MaxBig) == 1 {
|
||||
return BlockTSTooBigErr
|
||||
|
|
@ -254,6 +299,9 @@ func ValidateHeader(config *ChainConfig, pow pow.PoW, header *types.Header, pare
|
|||
// the difficulty that a new block should have when created at time
|
||||
// given the parent block's time and difficulty.
|
||||
func CalcDifficulty(config *ChainConfig, time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
|
||||
if config.FixedDifficulty != -1 {
|
||||
return big.NewInt(int64(config.FixedDifficulty))
|
||||
}
|
||||
if config.IsHomestead(new(big.Int).Add(parentNumber, common.Big1)) {
|
||||
return calcDifficultyHomestead(time, parentTime, parentNumber, parentDiff)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import (
|
|||
|
||||
// MakeChainConfig returns a new ChainConfig with the ethereum default chain settings.
|
||||
func MakeChainConfig() *ChainConfig {
|
||||
return &ChainConfig{HomesteadBlock: big.NewInt(0)}
|
||||
return &ChainConfig{HomesteadBlock: big.NewInt(0), FixedDifficulty: -1}
|
||||
}
|
||||
|
||||
// FakePow is a non-validating proof of work implementation.
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ type ChainConfig struct {
|
|||
HomesteadBlock *big.Int // homestead switch block
|
||||
|
||||
VmConfig vm.Config `json:"-"`
|
||||
|
||||
FixedDifficulty int
|
||||
}
|
||||
|
||||
// IsHomestead returns whether num is either equal to the homestead block or greater.
|
||||
|
|
|
|||
|
|
@ -75,4 +75,5 @@ type Backend interface {
|
|||
ChainDb() ethdb.Database
|
||||
DappDb() ethdb.Database
|
||||
EventMux() *event.TypeMux
|
||||
MinerPassphrase() string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,10 @@ type Config struct {
|
|||
|
||||
TestGenesisBlock *types.Block // Genesis block to seed the chain database with (testing only!)
|
||||
TestGenesisState ethdb.Database // Genesis state to seed the database with (testing only!)
|
||||
|
||||
FixedDifficulty int
|
||||
PollInterval int
|
||||
MinerPassphrase string
|
||||
}
|
||||
|
||||
type Ethereum struct {
|
||||
|
|
@ -144,6 +148,10 @@ type Ethereum struct {
|
|||
etherbase common.Address
|
||||
netVersionId int
|
||||
netRPCService *PublicNetAPI
|
||||
|
||||
fixedDifficulty int
|
||||
pollInterval int
|
||||
minerPassphrase string
|
||||
}
|
||||
|
||||
func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||
|
|
@ -220,6 +228,9 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
|||
GpobaseStepUp: config.GpobaseStepUp,
|
||||
GpobaseCorrectionFactor: config.GpobaseCorrectionFactor,
|
||||
httpclient: httpclient.New(config.DocRoot),
|
||||
fixedDifficulty: config.FixedDifficulty,
|
||||
pollInterval: config.PollInterval,
|
||||
minerPassphrase: config.MinerPassphrase,
|
||||
}
|
||||
switch {
|
||||
case config.PowTest:
|
||||
|
|
@ -383,6 +394,9 @@ func (self *Ethereum) SetEtherbase(etherbase common.Address) {
|
|||
func (s *Ethereum) StopMining() { s.miner.Stop() }
|
||||
func (s *Ethereum) IsMining() bool { return s.miner.Mining() }
|
||||
func (s *Ethereum) Miner() *miner.Miner { return s.miner }
|
||||
func (s *Ethereum) MinerPassphrase() string { return s.minerPassphrase }
|
||||
func (s *Ethereum) FixedDifficulty() int { return s.fixedDifficulty }
|
||||
func (s *Ethereum) PollInterval() int { return s.pollInterval }
|
||||
|
||||
func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager }
|
||||
func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain }
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"fmt"
|
||||
"math/big"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
|
|
@ -49,11 +50,13 @@ type Miner struct {
|
|||
|
||||
canStart int32 // can start indicates whether we can start the mining operation
|
||||
shouldStart int32 // should start indicates whether we should start after sync
|
||||
|
||||
}
|
||||
|
||||
func New(eth core.Backend, config *core.ChainConfig, mux *event.TypeMux, pow pow.PoW) *Miner {
|
||||
miner := &Miner{eth: eth, mux: mux, pow: pow, worker: newWorker(config, common.Address{}, eth), canStart: 1}
|
||||
go miner.update()
|
||||
go miner.runLoop()
|
||||
|
||||
return miner
|
||||
}
|
||||
|
|
@ -121,6 +124,24 @@ func (self *Miner) Start(coinbase common.Address, threads int) {
|
|||
self.worker.start()
|
||||
|
||||
self.worker.commitNewWork()
|
||||
|
||||
}
|
||||
|
||||
func (self *Miner) runLoop() {
|
||||
for true {
|
||||
if len(self.worker.current.txs) == 0 {
|
||||
if self.Mining() {
|
||||
glog.V(logger.Info).Infoln("Nothing to do. The miner sleeps.")
|
||||
self.Stop()
|
||||
}
|
||||
} else {
|
||||
if self.Mining() == false {
|
||||
glog.V(logger.Info).Infoln("A transaction awaits! Waking up miner.")
|
||||
self.Start(self.coinbase, self.threads)
|
||||
}
|
||||
}
|
||||
time.Sleep(self.eth.PollInterval() * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Miner) Stop() {
|
||||
|
|
|
|||
|
|
@ -548,7 +548,16 @@ func (self *worker) commitNewWork() {
|
|||
}
|
||||
|
||||
// create the new block whose nonce will be mined.
|
||||
work.Block = types.NewBlock(header, work.txs, uncles, work.receipts)
|
||||
newBlock := types.NewBlock(header, work.txs, uncles, work.receipts)
|
||||
sig, signError := self.signBlock(newBlock)
|
||||
if signError != nil {
|
||||
glog.V(logger.Info).Infoln(fmt.Sprintf("Error signing block: %s.", signError))
|
||||
return
|
||||
}
|
||||
newHeader := newBlock.Header()
|
||||
newHeader.Extra = sig
|
||||
signedBlock := types.NewBlock(newHeader, work.txs, uncles, work.receipts)
|
||||
work.Block = signedBlock
|
||||
|
||||
// We only care about logging if we're actually mining.
|
||||
if atomic.LoadInt32(&self.mining) == 1 {
|
||||
|
|
@ -558,6 +567,22 @@ func (self *worker) commitNewWork() {
|
|||
self.push(work)
|
||||
}
|
||||
|
||||
func (self *worker) signBlock(block *types.Block) ([]byte, error) {
|
||||
addr := block.Coinbase()
|
||||
header := block.Header()
|
||||
hash := core.HashOfHashes(header)
|
||||
acct := accounts.Account{Address: addr}
|
||||
unlockErr := self.eth.AccountManager().Unlock(acct, self.eth.MinerPassphrase())
|
||||
if unlockErr != nil {
|
||||
return nil, unlockErr
|
||||
}
|
||||
sig, err := self.eth.AccountManager().Sign(addr, hash.Bytes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sig, nil
|
||||
}
|
||||
|
||||
func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
|
||||
hash := uncle.Hash()
|
||||
if work.uncles.Has(hash) {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ package params
|
|||
import "math/big"
|
||||
|
||||
var (
|
||||
MaximumExtraDataSize = big.NewInt(32) // Maximum size extra data may be after Genesis.
|
||||
MaximumExtraDataSize = big.NewInt(128) // Maximum size extra data may be after Genesis.
|
||||
ExpByteGas = big.NewInt(10) // Times ceil(log256(exponent)) for the EXP instruction.
|
||||
SloadGas = big.NewInt(50) // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
|
||||
CallValueTransferGas = big.NewInt(9000) // Paid for CALL when the value transfer is non-zero.
|
||||
|
|
|
|||
19
wercker.yml
Normal file
19
wercker.yml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
box: golang
|
||||
build:
|
||||
steps:
|
||||
- setup-go-workspace
|
||||
- script:
|
||||
name: go build
|
||||
code: |
|
||||
make geth
|
||||
BIN=/pipeline/source/build/bin/$WERCKER_GIT_BRANCH/`cat VERSION`
|
||||
mkdir -p $BIN
|
||||
cp build/bin/geth $BIN/geth
|
||||
deploy:
|
||||
steps:
|
||||
- s3sync:
|
||||
source_dir: build/bin
|
||||
delete-removed: false
|
||||
bucket-url: $AWS_BUCKET_URL
|
||||
key-id: $AWS_ACCESS_KEY_ID
|
||||
key-secret: $AWS_SECRET_ACCESS_KEY
|
||||
Loading…
Reference in a new issue