فهرست منبع

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 سال پیش
والد
کامیت
d66f93cecd
4فایلهای تغییر یافته به همراه58 افزوده شده و 48 حذف شده
  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