Merge pull request #1428 from obscuren/coinbase-fixes

cmd,eth,rpc,tests: default coinbase
This commit is contained in:
Jeffrey Wilcke 2015-07-07 02:55:33 -07:00
commit e5fba8fd70
12 changed files with 99 additions and 51 deletions

View File

@ -461,22 +461,7 @@ func execJSFiles(ctx *cli.Context) {
func unlockAccount(ctx *cli.Context, am *accounts.Manager, addr string, i int) (addrHex, auth string) { func unlockAccount(ctx *cli.Context, am *accounts.Manager, addr string, i int) (addrHex, auth string) {
var err error var err error
// Load startup keys. XXX we are going to need a different format addrHex = utils.ParamToAddress(addr, am)
if !((len(addr) == 40) || (len(addr) == 42)) { // with or without 0x
var index int
index, err = strconv.Atoi(addr)
if err != nil {
utils.Fatalf("Invalid account address '%s'", addr)
}
addrHex, err = am.AddressByIndex(index)
if err != nil {
utils.Fatalf("%v", err)
}
} else {
addrHex = addr
}
// Attempt to unlock the account 3 times // Attempt to unlock the account 3 times
attempts := 3 attempts := 3
for tries := 0; tries < attempts; tries++ { for tries := 0; tries < attempts; tries++ {

View File

@ -9,6 +9,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv"
"github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics"
@ -122,8 +123,8 @@ var (
} }
EtherbaseFlag = cli.StringFlag{ EtherbaseFlag = cli.StringFlag{
Name: "etherbase", Name: "etherbase",
Usage: "Public address for block mining rewards. By default the address of your primary account is used", Usage: "Public address for block mining rewards. By default the address first created is used",
Value: "primary", Value: "0",
} }
GasPriceFlag = cli.StringFlag{ GasPriceFlag = cli.StringFlag{
Name: "gasprice", Name: "gasprice",
@ -351,6 +352,8 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
if len(customName) > 0 { if len(customName) > 0 {
clientID += "/" + customName clientID += "/" + customName
} }
am := MakeAccountManager(ctx)
return &eth.Config{ return &eth.Config{
Name: common.MakeName(clientID, version), Name: common.MakeName(clientID, version),
DataDir: ctx.GlobalString(DataDirFlag.Name), DataDir: ctx.GlobalString(DataDirFlag.Name),
@ -361,9 +364,9 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
LogFile: ctx.GlobalString(LogFileFlag.Name), LogFile: ctx.GlobalString(LogFileFlag.Name),
Verbosity: ctx.GlobalInt(VerbosityFlag.Name), Verbosity: ctx.GlobalInt(VerbosityFlag.Name),
LogJSON: ctx.GlobalString(LogJSONFlag.Name), LogJSON: ctx.GlobalString(LogJSONFlag.Name),
Etherbase: ctx.GlobalString(EtherbaseFlag.Name), Etherbase: common.HexToAddress(ParamToAddress(ctx.GlobalString(EtherbaseFlag.Name), am)),
MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name), MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name),
AccountManager: MakeAccountManager(ctx), AccountManager: am,
VmDebug: ctx.GlobalBool(VMDebugFlag.Name), VmDebug: ctx.GlobalBool(VMDebugFlag.Name),
MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name), MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name),
MaxPendingPeers: ctx.GlobalInt(MaxPendingPeersFlag.Name), MaxPendingPeers: ctx.GlobalInt(MaxPendingPeersFlag.Name),
@ -488,3 +491,20 @@ func StartPProf(ctx *cli.Context) {
log.Println(http.ListenAndServe(address, nil)) log.Println(http.ListenAndServe(address, nil))
}() }()
} }
func ParamToAddress(addr string, am *accounts.Manager) (addrHex string) {
if !((len(addr) == 40) || (len(addr) == 42)) { // with or without 0x
index, err := strconv.Atoi(addr)
if err != nil {
Fatalf("Invalid account address '%s'", addr)
}
addrHex, err = am.AddressByIndex(index)
if err != nil {
Fatalf("%v", err)
}
} else {
addrHex = addr
}
return
}

View File

@ -88,7 +88,7 @@ type Config struct {
Shh bool Shh bool
Dial bool Dial bool
Etherbase string Etherbase common.Address
GasPrice *big.Int GasPrice *big.Int
MinerThreads int MinerThreads int
AccountManager *accounts.Manager AccountManager *accounts.Manager
@ -324,7 +324,7 @@ func New(config *Config) (*Ethereum, error) {
eventMux: &event.TypeMux{}, eventMux: &event.TypeMux{},
accountManager: config.AccountManager, accountManager: config.AccountManager,
DataDir: config.DataDir, DataDir: config.DataDir,
etherbase: common.HexToAddress(config.Etherbase), etherbase: config.Etherbase,
clientVersion: config.Name, // TODO should separate from Name clientVersion: config.Name, // TODO should separate from Name
netVersionId: config.NetworkId, netVersionId: config.NetworkId,
NatSpec: config.NatSpec, NatSpec: config.NatSpec,
@ -480,6 +480,12 @@ func (s *Ethereum) Etherbase() (eb common.Address, err error) {
return return
} }
// set in js console via admin interface or wrapper from cli flags
func (self *Ethereum) SetEtherbase(etherbase common.Address) {
self.etherbase = etherbase
self.miner.SetEtherbase(etherbase)
}
func (s *Ethereum) StopMining() { s.miner.Stop() } func (s *Ethereum) StopMining() { s.miner.Stop() }
func (s *Ethereum) IsMining() bool { return s.miner.Mining() } func (s *Ethereum) IsMining() bool { return s.miner.Mining() }
func (s *Ethereum) Miner() *miner.Miner { return s.miner } func (s *Ethereum) Miner() *miner.Miner { return s.miner }

View File

@ -137,3 +137,8 @@ func (self *Miner) PendingState() *state.StateDB {
func (self *Miner) PendingBlock() *types.Block { func (self *Miner) PendingBlock() *types.Block {
return self.worker.pendingBlock() return self.worker.pendingBlock()
} }
func (self *Miner) SetEtherbase(addr common.Address) {
self.coinbase = addr
self.worker.setEtherbase(addr)
}

View File

@ -124,6 +124,12 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker {
return worker return worker
} }
func (self *worker) setEtherbase(addr common.Address) {
self.mu.Lock()
defer self.mu.Unlock()
self.coinbase = addr
}
func (self *worker) pendingState() *state.StateDB { func (self *worker) pendingState() *state.StateDB {
self.currentMu.Lock() self.currentMu.Lock()
defer self.currentMu.Unlock() defer self.currentMu.Unlock()

View File

@ -19,6 +19,7 @@ var (
"miner_makeDAG": (*minerApi).MakeDAG, "miner_makeDAG": (*minerApi).MakeDAG,
"miner_setExtra": (*minerApi).SetExtra, "miner_setExtra": (*minerApi).SetExtra,
"miner_setGasPrice": (*minerApi).SetGasPrice, "miner_setGasPrice": (*minerApi).SetGasPrice,
"miner_setEtherbase": (*minerApi).SetEtherbase,
"miner_startAutoDAG": (*minerApi).StartAutoDAG, "miner_startAutoDAG": (*minerApi).StartAutoDAG,
"miner_start": (*minerApi).StartMiner, "miner_start": (*minerApi).StartMiner,
"miner_stopAutoDAG": (*minerApi).StopAutoDAG, "miner_stopAutoDAG": (*minerApi).StopAutoDAG,
@ -119,6 +120,15 @@ func (self *minerApi) SetGasPrice(req *shared.Request) (interface{}, error) {
return true, nil return true, nil
} }
func (self *minerApi) SetEtherbase(req *shared.Request) (interface{}, error) {
args := new(SetEtherbaseArgs)
if err := self.codec.Decode(req.Params, &args); err != nil {
return false, err
}
self.ethereum.SetEtherbase(args.Etherbase)
return nil, nil
}
func (self *minerApi) StartAutoDAG(req *shared.Request) (interface{}, error) { func (self *minerApi) StartAutoDAG(req *shared.Request) (interface{}, error) {
self.ethereum.StartAutoDAG() self.ethereum.StartAutoDAG()
return true, nil return true, nil

View File

@ -5,6 +5,7 @@ import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rpc/shared" "github.com/ethereum/go-ethereum/rpc/shared"
) )
@ -76,6 +77,31 @@ func (args *GasPriceArgs) UnmarshalJSON(b []byte) (err error) {
return shared.NewInvalidTypeError("Price", "not a string") return shared.NewInvalidTypeError("Price", "not a string")
} }
type SetEtherbaseArgs struct {
Etherbase common.Address
}
func (args *SetEtherbaseArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return shared.NewDecodeParamError(err.Error())
}
if len(obj) < 1 {
return shared.NewInsufficientParamsError(len(obj), 1)
}
if addr, ok := obj[0].(string); ok {
args.Etherbase = common.HexToAddress(addr)
if (args.Etherbase == common.Address{}) {
return shared.NewInvalidTypeError("Etherbase", "not a valid address")
}
return nil
}
return shared.NewInvalidTypeError("Etherbase", "not a string")
}
type MakeDAGArgs struct { type MakeDAGArgs struct {
BlockNumber int64 BlockNumber int64
} }

View File

@ -17,6 +17,13 @@ web3._extend({
params: 1, params: 1,
inputFormatter: [null] inputFormatter: [null]
}), }),
new web3._extend.Method({
name: 'setEtherbase',
call: 'miner_setEtherbase',
params: 1,
inputFormatter: [web3._extend.formatters.formatInputInt],
outputFormatter: web3._extend.formatters.formatOutputBool
}),
new web3._extend.Method({ new web3._extend.Method({
name: 'setExtra', name: 'setExtra',
call: 'miner_setExtra', call: 'miner_setExtra',

View File

@ -180,7 +180,7 @@ func (test *BlockTest) makeEthConfig() *eth.Config {
return &eth.Config{ return &eth.Config{
DataDir: common.DefaultDataDir(), DataDir: common.DefaultDataDir(),
Verbosity: 5, Verbosity: 5,
Etherbase: "primary", Etherbase: common.Address{},
AccountManager: accounts.NewManager(ks), AccountManager: accounts.NewManager(ks),
NewDB: func(path string) (common.Database, error) { return ethdb.NewMemDatabase() }, NewDB: func(path string) (common.Database, error) { return ethdb.NewMemDatabase() },
} }

View File

@ -2,6 +2,7 @@ package tests
import ( import (
"bytes" "bytes"
"encoding/hex"
"fmt" "fmt"
"io" "io"
"math/big" "math/big"
@ -147,13 +148,12 @@ func runStateTest(test VmTest) error {
func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) { func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) {
var ( var (
keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"]))) data = common.FromHex(tx["data"])
data = common.FromHex(tx["data"]) gas = common.Big(tx["gasLimit"])
gas = common.Big(tx["gasLimit"]) price = common.Big(tx["gasPrice"])
price = common.Big(tx["gasPrice"]) value = common.Big(tx["value"])
value = common.Big(tx["value"]) nonce = common.Big(tx["nonce"]).Uint64()
nonce = common.Big(tx["nonce"]).Uint64() caddr = common.HexToAddress(env["currentCoinbase"])
caddr = common.HexToAddress(env["currentCoinbase"])
) )
var to *common.Address var to *common.Address
@ -168,9 +168,11 @@ func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.
coinbase := statedb.GetOrNewStateObject(caddr) coinbase := statedb.GetOrNewStateObject(caddr)
coinbase.SetGasLimit(common.Big(env["currentGasLimit"])) coinbase.SetGasLimit(common.Big(env["currentGasLimit"]))
message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce) key, _ := hex.DecodeString(tx["secretKey"])
addr := crypto.PubkeyToAddress(crypto.ToECDSA(key).PublicKey)
message := NewMessage(addr, to, data, value, gas, price, nonce)
vmenv := NewEnvFromMap(statedb, env, tx) vmenv := NewEnvFromMap(statedb, env, tx)
vmenv.origin = common.BytesToAddress(keyPair.Address()) vmenv.origin = addr
ret, _, err := core.ApplyMessage(vmenv, message, coinbase) ret, _, err := core.ApplyMessage(vmenv, message, coinbase)
if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || state.IsGasLimitErr(err) { if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || state.IsGasLimitErr(err) {
statedb.Set(snapshot) statedb.Set(snapshot)

View File

@ -168,16 +168,6 @@ func (self *Transaction) ToString() string {
return self.ref.String() return self.ref.String()
} }
type Key struct {
Address string `json:"address"`
PrivateKey string `json:"privateKey"`
PublicKey string `json:"publicKey"`
}
func NewKey(key *crypto.KeyPair) *Key {
return &Key{common.ToHex(key.Address()), common.ToHex(key.PrivateKey), common.ToHex(key.PublicKey)}
}
type PReceipt struct { type PReceipt struct {
CreatedContract bool `json:"createdContract"` CreatedContract bool `json:"createdContract"`
Address string `json:"address"` Address string `json:"address"`

View File

@ -476,15 +476,6 @@ func (self *XEth) IsContract(address string) bool {
return len(self.State().SafeGet(address).Code()) > 0 return len(self.State().SafeGet(address).Code()) > 0
} }
func (self *XEth) SecretToAddress(key string) string {
pair, err := crypto.NewKeyPairFromSec(common.FromHex(key))
if err != nil {
return ""
}
return common.ToHex(pair.Address())
}
func (self *XEth) UninstallFilter(id int) bool { func (self *XEth) UninstallFilter(id int) bool {
defer self.filterManager.UninstallFilter(id) defer self.filterManager.UninstallFilter(id)