accounts, core, eth, xeth: use account manager for everything
The account manager is now responsible for picking the default account and the coinbase.
This commit is contained in:
parent
bc45e5c6de
commit
d66f93cecd
@ -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 {
|
||||||
|
18
xeth/xeth.go
18
xeth/xeth.go
@ -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…
Reference in New Issue
Block a user