Browse Source

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

The account manager is now responsible for picking the
default account and the coinbase.
Felix Lange 10 years ago
parent
commit
d66f93cecd
4 changed files with 58 additions and 48 deletions
  1. 32 7
      accounts/account_manager.go
  2. 0 2
      core/manager.go
  3. 14 33
      eth/backend.go
  4. 12 6
      xeth/xeth.go

+ 32 - 7
accounts/account_manager.go

@@ -42,7 +42,10 @@ import (
 	"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?
 type Account struct {
@@ -56,17 +59,39 @@ type AccountManager struct {
 	mutex              sync.RWMutex
 }
 
-func NewAccountManager(keyStore crypto.KeyStore2, unlockMilliseconds time.Duration) AccountManager {
-	keysMap := make(map[string]crypto.Key)
-	am := &AccountManager{
+func NewAccountManager(keyStore crypto.KeyStore2, unlockMilliseconds time.Duration) *AccountManager {
+	return &AccountManager{
 		keyStore:           keyStore,
-		unlockedKeys:       keysMap,
+		unlockedKeys:       make(map[string]crypto.Key),
 		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)
 }
 

+ 0 - 2
core/manager.go

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

+ 14 - 33
eth/backend.go

@@ -38,11 +38,9 @@ var (
 
 type Config struct {
 	Name      string
-	KeyStore  string
 	DataDir   string
 	LogFile   string
 	LogLevel  int
-	KeyRing   string
 	LogFormat string
 
 	MaxPeers int
@@ -60,9 +58,8 @@ type Config struct {
 	Shh  bool
 	Dial bool
 
-	MinerThreads int
-
-	KeyManager *crypto.KeyManager
+	MinerThreads   int
+	AccountManager *accounts.AccountManager
 }
 
 func (cfg *Config) parseBootNodes() []*discover.Node {
@@ -127,8 +124,7 @@ type Ethereum struct {
 	blockSub event.Subscription
 	miner    *miner.Miner
 
-	RpcServer  rpc.RpcServer
-	keyManager *crypto.KeyManager
+	RpcServer rpc.RpcServer
 
 	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)
 	}
 
-	// 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)
 	//ethutil.Config.Db = db
 
 	eth := &Ethereum{
-		shutdownChan: make(chan bool),
-		db:           db,
-		keyManager:   keyManager,
-		eventMux:     &event.TypeMux{},
-		logger:       ethlogger,
-		DataDir:      config.DataDir,
+		shutdownChan:   make(chan bool),
+		db:             db,
+		eventMux:       &event.TypeMux{},
+		logger:         ethlogger,
+		accountManager: config.AccountManager,
+		DataDir:        config.DataDir,
 	}
 
-	// TODO: add config flag and case on plain/protected key store
-	ks := crypto.NewKeyStorePlain(ethutil.DefaultDataDir())
-	am := accounts.NewAccountManager(ks, 300000) // keys unlocked for 300s
-	eth.accountManager = &am
+	cb, err := eth.accountManager.Coinbase()
+	if err != nil {
+		return nil, fmt.Errorf("no coinbase: %v", err)
+	}
 
 	eth.chainManager = core.NewChainManager(db, eth.EventMux())
 	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.chainManager.SetProcessor(eth.blockProcessor)
 	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
 	insertChain := eth.chainManager.InsertChain
@@ -221,7 +204,6 @@ func New(config *Config) (*Ethereum, error) {
 	return eth, nil
 }
 
-func (s *Ethereum) KeyManager() *crypto.KeyManager           { return s.keyManager }
 func (s *Ethereum) Logger() logger.LogSystem                 { return s.logger }
 func (s *Ethereum) Name() string                             { return s.net.Name }
 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) Peers() []*p2p.Peer                       { return s.net.Peers() }
 func (s *Ethereum) MaxPeers() int                            { return s.net.MaxPeers }
-func (s *Ethereum) Coinbase() []byte                         { return nil } // TODO
 
 // Start the ethereum
 func (s *Ethereum) Start() error {

+ 12 - 6
xeth/xeth.go

@@ -32,7 +32,6 @@ type Backend interface {
 	PeerCount() int
 	IsListening() bool
 	Peers() []*p2p.Peer
-	KeyManager() *crypto.KeyManager
 	Db() ethutil.Database
 	EventMux() *event.TypeMux
 	Whisper() *whisper.Whisper
@@ -142,7 +141,8 @@ func (self *XEth) IsListening() bool {
 }
 
 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 {
@@ -251,10 +251,13 @@ func (self *XEth) Call(toStr, valueStr, gasStr, gasPriceStr, dataStr string) (st
 		gasPriceStr = "1"
 	}
 
+	acct, err := self.accountManager.Default()
+	if err != nil {
+		return "", err
+	}
 	var (
 		statedb = self.State().State() //self.chainManager.TransState()
-		key     = self.eth.KeyManager().KeyPair()
-		from    = statedb.GetOrNewStateObject(key.Address())
+		from    = statedb.GetOrNewStateObject(acct.Address)
 		block   = self.chainManager.CurrentBlock()
 		to      = statedb.GetOrNewStateObject(fromHex(toStr))
 		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.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)
-
 	res, err := vmenv.Call(from, to.Address(), data, gas, price, value)
 	if err != nil {
 		return "", err