accounts, core, eth, xeth: use account manager for everything

The account manager is now responsible for picking the
default account and the coinbase.
pull/447/head
Felix Lange 10 years ago
parent bc45e5c6de
commit d66f93cecd
  1. 39
      accounts/account_manager.go
  2. 2
      core/manager.go
  3. 47
      eth/backend.go
  4. 18
      xeth/xeth.go

@ -42,7 +42,10 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
) )
var ErrLocked = errors.New("account is locked; please request passphrase") var (
ErrLocked = errors.New("account is locked")
ErrNoKeys = errors.New("no keys in store")
)
// TODO: better name for this struct? // TODO: better name for this struct?
type Account struct { type Account struct {
@ -56,17 +59,39 @@ type AccountManager struct {
mutex sync.RWMutex mutex sync.RWMutex
} }
func NewAccountManager(keyStore crypto.KeyStore2, unlockMilliseconds time.Duration) AccountManager { func NewAccountManager(keyStore crypto.KeyStore2, unlockMilliseconds time.Duration) *AccountManager {
keysMap := make(map[string]crypto.Key) return &AccountManager{
am := &AccountManager{
keyStore: keyStore, keyStore: keyStore,
unlockedKeys: keysMap, unlockedKeys: make(map[string]crypto.Key),
unlockMilliseconds: unlockMilliseconds, unlockMilliseconds: unlockMilliseconds,
} }
return *am
} }
func (am AccountManager) DeleteAccount(address []byte, auth string) error { // Coinbase returns the account address that mining rewards are sent to.
func (am *AccountManager) Coinbase() (addr []byte, err error) {
// TODO: persist coinbase address on disk
return am.firstAddr()
}
// MainAccount returns the primary account used for transactions.
func (am *AccountManager) Default() (*Account, error) {
// TODO: persist main account address on disk
addr, err := am.firstAddr()
return &Account{Address: addr}, err
}
func (am *AccountManager) firstAddr() ([]byte, error) {
addrs, err := am.keyStore.GetKeyAddresses()
if err != nil {
return nil, err
}
if len(addrs) == 0 {
return nil, ErrNoKeys
}
return addrs[0], nil
}
func (am *AccountManager) DeleteAccount(address []byte, auth string) error {
return am.keyStore.DeleteKey(address, auth) return am.keyStore.DeleteKey(address, auth)
} }

@ -1,7 +1,6 @@
package core package core
import ( import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
@ -14,7 +13,6 @@ type Backend interface {
PeerCount() int PeerCount() int
IsListening() bool IsListening() bool
Peers() []*p2p.Peer Peers() []*p2p.Peer
KeyManager() *crypto.KeyManager
Db() ethutil.Database Db() ethutil.Database
EventMux() *event.TypeMux EventMux() *event.TypeMux
} }

@ -38,11 +38,9 @@ var (
type Config struct { type Config struct {
Name string Name string
KeyStore string
DataDir string DataDir string
LogFile string LogFile string
LogLevel int LogLevel int
KeyRing string
LogFormat string LogFormat string
MaxPeers int MaxPeers int
@ -60,9 +58,8 @@ type Config struct {
Shh bool Shh bool
Dial bool Dial bool
MinerThreads int MinerThreads int
AccountManager *accounts.AccountManager
KeyManager *crypto.KeyManager
} }
func (cfg *Config) parseBootNodes() []*discover.Node { func (cfg *Config) parseBootNodes() []*discover.Node {
@ -127,8 +124,7 @@ type Ethereum struct {
blockSub event.Subscription blockSub event.Subscription
miner *miner.Miner miner *miner.Miner
RpcServer rpc.RpcServer RpcServer rpc.RpcServer
keyManager *crypto.KeyManager
logger logger.LogSystem logger logger.LogSystem
@ -153,35 +149,22 @@ func New(config *Config) (*Ethereum, error) {
return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, path) return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, path)
} }
// Create new keymanager
var keyManager *crypto.KeyManager
switch config.KeyStore {
case "db":
keyManager = crypto.NewDBKeyManager(db)
case "file":
keyManager = crypto.NewFileKeyManager(config.DataDir)
default:
return nil, fmt.Errorf("unknown keystore type: %s", config.KeyStore)
}
// Initialise the keyring
keyManager.Init(config.KeyRing, 0, false)
saveProtocolVersion(db) saveProtocolVersion(db)
//ethutil.Config.Db = db //ethutil.Config.Db = db
eth := &Ethereum{ eth := &Ethereum{
shutdownChan: make(chan bool), shutdownChan: make(chan bool),
db: db, db: db,
keyManager: keyManager, eventMux: &event.TypeMux{},
eventMux: &event.TypeMux{}, logger: ethlogger,
logger: ethlogger, accountManager: config.AccountManager,
DataDir: config.DataDir, DataDir: config.DataDir,
} }
// TODO: add config flag and case on plain/protected key store cb, err := eth.accountManager.Coinbase()
ks := crypto.NewKeyStorePlain(ethutil.DefaultDataDir()) if err != nil {
am := accounts.NewAccountManager(ks, 300000) // keys unlocked for 300s return nil, fmt.Errorf("no coinbase: %v", err)
eth.accountManager = &am }
eth.chainManager = core.NewChainManager(db, eth.EventMux()) eth.chainManager = core.NewChainManager(db, eth.EventMux())
pow := ethash.New(eth.chainManager) pow := ethash.New(eth.chainManager)
@ -189,7 +172,7 @@ func New(config *Config) (*Ethereum, error) {
eth.blockProcessor = core.NewBlockProcessor(db, pow, eth.txPool, eth.chainManager, eth.EventMux()) eth.blockProcessor = core.NewBlockProcessor(db, pow, eth.txPool, eth.chainManager, eth.EventMux())
eth.chainManager.SetProcessor(eth.blockProcessor) eth.chainManager.SetProcessor(eth.blockProcessor)
eth.whisper = whisper.New() eth.whisper = whisper.New()
eth.miner = miner.New(keyManager.Address(), eth, pow, config.MinerThreads) eth.miner = miner.New(cb, eth, pow, config.MinerThreads)
hasBlock := eth.chainManager.HasBlock hasBlock := eth.chainManager.HasBlock
insertChain := eth.chainManager.InsertChain insertChain := eth.chainManager.InsertChain
@ -221,7 +204,6 @@ func New(config *Config) (*Ethereum, error) {
return eth, nil return eth, nil
} }
func (s *Ethereum) KeyManager() *crypto.KeyManager { return s.keyManager }
func (s *Ethereum) Logger() logger.LogSystem { return s.logger } func (s *Ethereum) Logger() logger.LogSystem { return s.logger }
func (s *Ethereum) Name() string { return s.net.Name } func (s *Ethereum) Name() string { return s.net.Name }
func (s *Ethereum) AccountManager() *accounts.AccountManager { return s.accountManager } func (s *Ethereum) AccountManager() *accounts.AccountManager { return s.accountManager }
@ -237,7 +219,6 @@ func (s *Ethereum) IsListening() bool { return true } //
func (s *Ethereum) PeerCount() int { return s.net.PeerCount() } func (s *Ethereum) PeerCount() int { return s.net.PeerCount() }
func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() } func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() }
func (s *Ethereum) MaxPeers() int { return s.net.MaxPeers } func (s *Ethereum) MaxPeers() int { return s.net.MaxPeers }
func (s *Ethereum) Coinbase() []byte { return nil } // TODO
// Start the ethereum // Start the ethereum
func (s *Ethereum) Start() error { func (s *Ethereum) Start() error {

@ -32,7 +32,6 @@ type Backend interface {
PeerCount() int PeerCount() int
IsListening() bool IsListening() bool
Peers() []*p2p.Peer Peers() []*p2p.Peer
KeyManager() *crypto.KeyManager
Db() ethutil.Database Db() ethutil.Database
EventMux() *event.TypeMux EventMux() *event.TypeMux
Whisper() *whisper.Whisper Whisper() *whisper.Whisper
@ -142,7 +141,8 @@ func (self *XEth) IsListening() bool {
} }
func (self *XEth) Coinbase() string { func (self *XEth) Coinbase() string {
return toHex(self.eth.KeyManager().Address()) cb, _ := self.eth.AccountManager().Coinbase()
return toHex(cb)
} }
func (self *XEth) NumberToHuman(balance string) string { func (self *XEth) NumberToHuman(balance string) string {
@ -251,10 +251,13 @@ func (self *XEth) Call(toStr, valueStr, gasStr, gasPriceStr, dataStr string) (st
gasPriceStr = "1" gasPriceStr = "1"
} }
acct, err := self.accountManager.Default()
if err != nil {
return "", err
}
var ( var (
statedb = self.State().State() //self.chainManager.TransState() statedb = self.State().State() //self.chainManager.TransState()
key = self.eth.KeyManager().KeyPair() from = statedb.GetOrNewStateObject(acct.Address)
from = statedb.GetOrNewStateObject(key.Address())
block = self.chainManager.CurrentBlock() block = self.chainManager.CurrentBlock()
to = statedb.GetOrNewStateObject(fromHex(toStr)) to = statedb.GetOrNewStateObject(fromHex(toStr))
data = fromHex(dataStr) data = fromHex(dataStr)
@ -264,9 +267,12 @@ func (self *XEth) Call(toStr, valueStr, gasStr, gasPriceStr, dataStr string) (st
) )
msg := types.NewTransactionMessage(fromHex(toStr), value, gas, price, data) msg := types.NewTransactionMessage(fromHex(toStr), value, gas, price, data)
msg.Sign(key.PrivateKey) sig, err := self.accountManager.Sign(acct, msg.Hash())
if err != nil {
return "", err
}
msg.SetSignatureValues(sig)
vmenv := core.NewEnv(statedb, self.chainManager, msg, block) vmenv := core.NewEnv(statedb, self.chainManager, msg, block)
res, err := vmenv.Call(from, to.Address(), data, gas, price, value) res, err := vmenv.Call(from, to.Address(), data, gas, price, value)
if err != nil { if err != nil {
return "", err return "", err

Loading…
Cancel
Save