refactor move manager.go into seperated package to avoid cyclic import

This commit is contained in:
Huiyi Li 2020-04-06 14:43:52 -07:00
parent 7f6c0fb601
commit 276e13dc01
19 changed files with 115 additions and 71 deletions

View file

@ -21,7 +21,6 @@ import (
crand "crypto/rand" crand "crypto/rand"
"fmt" "fmt"
"math/big" "math/big"
"reflect"
"sync" "sync"
"time" "time"
@ -33,9 +32,6 @@ import (
"github.com/pborman/uuid" "github.com/pborman/uuid"
) )
// DBKeyStoreType is the reflect type of a keystore backend.
var DBKeyStoreType = reflect.TypeOf(&keyStoreDB{})
type keyStoreDB struct { type keyStoreDB struct {
storage *keyStorePassphraseDB // storage backend, might be mysql or postgres storage *keyStorePassphraseDB // storage backend, might be mysql or postgres
unlocked map[common.Address]*unlocked // Currently unlocked account (decrypted private keys) unlocked map[common.Address]*unlocked // Currently unlocked account (decrypted private keys)

View file

@ -26,7 +26,6 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"os" "os"
"reflect"
"runtime" "runtime"
"sync" "sync"
"time" "time"
@ -38,9 +37,6 @@ import (
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
) )
// FSKeyStoreType is the reflect type of a keystore backend.
var FSKeyStoreType = reflect.TypeOf(&keyStoreFS{})
// Maximum time between wallet refreshes (if filesystem notifications don't work). // Maximum time between wallet refreshes (if filesystem notifications don't work).
const walletRefreshCycle = 3 * time.Second const walletRefreshCycle = 3 * time.Second

View file

@ -5,6 +5,7 @@ import (
"errors" "errors"
"math/big" "math/big"
"path/filepath" "path/filepath"
"reflect"
"time" "time"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
@ -25,6 +26,12 @@ const KeyStoreScheme = "keystore"
const keystoreDBTableName = "keystore" const keystoreDBTableName = "keystore"
// DBKeyStoreType is the reflect type of a keystore backend.
var DBKeyStoreType = reflect.TypeOf(&keyStoreDB{})
// FSKeyStoreType is the reflect type of a keystore backend.
var FSKeyStoreType = reflect.TypeOf(&keyStoreFS{})
// KeyStore is the interface which abstracts all needed operations required // KeyStore is the interface which abstracts all needed operations required
type KeyStore interface { type KeyStore interface {
// Wallets implements accounts.Backend, returning all single-key wallets from the KeyStore. // Wallets implements accounts.Backend, returning all single-key wallets from the KeyStore.

View file

@ -14,13 +14,15 @@
// You should have received a copy of the GNU Lesser General Public License // You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package accounts package manager
import ( import (
"reflect" "reflect"
"sort" "sort"
"sync" "sync"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
) )
@ -36,11 +38,11 @@ type Config struct {
// Manager is an overarching account manager that can communicate with various // Manager is an overarching account manager that can communicate with various
// backends for signing transactions. // backends for signing transactions.
type Manager struct { type Manager struct {
config *Config // Global account manager configurations config *Config // Global account manager configurations
backends map[reflect.Type][]Backend // Index of backends currently registered backends map[reflect.Type][]accounts.Backend // Index of backends currently registered
updaters []event.Subscription // Wallet update subscriptions for all backends updaters []event.Subscription // Wallet update subscriptions for all backends
updates chan WalletEvent // Subscription sink for backend wallet changes updates chan accounts.WalletEvent // Subscription sink for backend wallet changes
wallets []Wallet // Cache of all wallets from all registered backends wallets []accounts.Wallet // Cache of all wallets from all registered backends
feed event.Feed // Wallet feed notifying of arrivals/departures feed event.Feed // Wallet feed notifying of arrivals/departures
@ -50,14 +52,17 @@ type Manager struct {
// NewManager creates a generic account manager to sign transaction via various // NewManager creates a generic account manager to sign transaction via various
// supported backends. // supported backends.
func NewManager(config *Config, backends ...Backend) *Manager { func NewManager(config *Config, backends ...accounts.Backend) *Manager {
// Retrieve the initial list of wallets from the backends and sort by URL // Retrieve the initial list of wallets from the backends and sort by URL
var wallets []Wallet var wallets []accounts.Wallet
for _, backend := range backends { for _, backend := range backends {
wallets = merge(wallets, backend.Wallets()...) // if we are using db backed keystore, it doesn't make sense to cache the potential millions of keys in our memory
if reflect.TypeOf(backend) != keystore.DBKeyStoreType {
wallets = backend.Wallets()
}
} }
// Subscribe to wallet notifications from all backends // Subscribe to wallet notifications from all backends
updates := make(chan WalletEvent, 4*len(backends)) updates := make(chan accounts.WalletEvent, 4*len(backends))
subs := make([]event.Subscription, len(backends)) subs := make([]event.Subscription, len(backends))
for i, backend := range backends { for i, backend := range backends {
@ -66,7 +71,7 @@ func NewManager(config *Config, backends ...Backend) *Manager {
// Assemble the account manager and return // Assemble the account manager and return
am := &Manager{ am := &Manager{
config: config, config: config,
backends: make(map[reflect.Type][]Backend), backends: make(map[reflect.Type][]accounts.Backend),
updaters: subs, updaters: subs,
updates: updates, updates: updates,
wallets: wallets, wallets: wallets,
@ -113,9 +118,9 @@ func (am *Manager) update() {
// Wallet event arrived, update local cache // Wallet event arrived, update local cache
am.lock.Lock() am.lock.Lock()
switch event.Kind { switch event.Kind {
case WalletArrived: case accounts.WalletArrived:
am.wallets = merge(am.wallets, event.Wallet) am.wallets = merge(am.wallets, event.Wallet)
case WalletDropped: case accounts.WalletDropped:
am.wallets = drop(am.wallets, event.Wallet) am.wallets = drop(am.wallets, event.Wallet)
} }
am.lock.Unlock() am.lock.Unlock()
@ -132,8 +137,8 @@ func (am *Manager) update() {
} }
// Backends retrieves the backend(s) with the given type from the account manager. // Backends retrieves the backend(s) with the given type from the account manager.
func (am *Manager) Backends(kinds ...reflect.Type) []Backend { func (am *Manager) Backends(kinds ...reflect.Type) []accounts.Backend {
backends := make([]Backend, 0) backends := make([]accounts.Backend, 0)
for _, kind := range kinds { for _, kind := range kinds {
backends = append(backends, am.backends[kind]...) backends = append(backends, am.backends[kind]...)
} }
@ -141,21 +146,27 @@ func (am *Manager) Backends(kinds ...reflect.Type) []Backend {
} }
// Wallets returns all signer accounts registered under this account manager. // Wallets returns all signer accounts registered under this account manager.
func (am *Manager) Wallets() []Wallet { func (am *Manager) Wallets() []accounts.Wallet {
am.lock.RLock() am.lock.RLock()
defer am.lock.RUnlock() defer am.lock.RUnlock()
cpy := make([]Wallet, len(am.wallets)) dbBackends := am.Backends(keystore.DBKeyStoreType)
copy(cpy, am.wallets) var wallets []accounts.Wallet
return cpy if len(dbBackends) == 1 {
wallets = dbBackends[0].Wallets()
} else {
wallets = make([]accounts.Wallet, 0)
}
wallets = append(wallets, am.wallets...)
return wallets
} }
// Wallet retrieves the wallet associated with a particular URL. // Wallet retrieves the wallet associated with a particular URL.
func (am *Manager) Wallet(url string) (Wallet, error) { func (am *Manager) Wallet(url string) (accounts.Wallet, error) {
am.lock.RLock() am.lock.RLock()
defer am.lock.RUnlock() defer am.lock.RUnlock()
parsed, err := parseURL(url) parsed, err := accounts.ParseURL(url)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -164,7 +175,7 @@ func (am *Manager) Wallet(url string) (Wallet, error) {
return wallet, nil return wallet, nil
} }
} }
return nil, ErrUnknownWallet return nil, accounts.ErrUnknownWallet
} }
// Accounts returns all account addresses of all wallets within the account manager // Accounts returns all account addresses of all wallets within the account manager
@ -172,7 +183,19 @@ func (am *Manager) Accounts() []common.Address {
am.lock.RLock() am.lock.RLock()
defer am.lock.RUnlock() defer am.lock.RUnlock()
addresses := make([]common.Address, 0) // return [] instead of nil if empty var addresses []common.Address
dbBackends := am.Backends(keystore.DBKeyStoreType)
if len(dbBackends) == 1 {
dbWallets := dbBackends[0].Wallets()
addresses = make([]common.Address, len(dbWallets))
for i, wallet := range dbWallets {
// one dbWallet only have one account inside
addresses[i] = wallet.Accounts()[0].Address
}
} else {
addresses = make([]common.Address, 0) // return [] instead of nil if empty
}
for _, wallet := range am.wallets { for _, wallet := range am.wallets {
for _, account := range wallet.Accounts() { for _, account := range wallet.Accounts() {
addresses = append(addresses, account.Address) addresses = append(addresses, account.Address)
@ -184,21 +207,33 @@ func (am *Manager) Accounts() []common.Address {
// Find attempts to locate the wallet corresponding to a specific account. Since // Find attempts to locate the wallet corresponding to a specific account. Since
// accounts can be dynamically added to and removed from wallets, this method has // accounts can be dynamically added to and removed from wallets, this method has
// a linear runtime in the number of wallets. // a linear runtime in the number of wallets.
func (am *Manager) Find(account Account) (Wallet, error) { func (am *Manager) Find(account accounts.Account) (accounts.Wallet, error) {
am.lock.RLock() am.lock.RLock()
defer am.lock.RUnlock() defer am.lock.RUnlock()
dbBackends := am.Backends(keystore.DBKeyStoreType)
if len(dbBackends) == 1 {
dbKeyStore, _ := dbBackends[0].(keystore.KeyStore)
// TODO here
dbKeyStore.Accounts()
return nil, nil
// acc, err := dbKeyStore.Find(account)
// if err == nil {
// return &keystore.keystoreWalletDB{}, nil
// }
}
for _, wallet := range am.wallets { for _, wallet := range am.wallets {
if wallet.Contains(account) { if wallet.Contains(account) {
return wallet, nil return wallet, nil
} }
} }
return nil, ErrUnknownAccount return nil, accounts.ErrUnknownAccount
} }
// Subscribe creates an async subscription to receive notifications when the // Subscribe creates an async subscription to receive notifications when the
// manager detects the arrival or departure of a wallet from any of its backends. // manager detects the arrival or departure of a wallet from any of its backends.
func (am *Manager) Subscribe(sink chan<- WalletEvent) event.Subscription { func (am *Manager) Subscribe(sink chan<- accounts.WalletEvent) event.Subscription {
return am.feed.Subscribe(sink) return am.feed.Subscribe(sink)
} }
@ -206,21 +241,21 @@ func (am *Manager) Subscribe(sink chan<- WalletEvent) event.Subscription {
// origin list is preserved by inserting new wallets at the correct position. // origin list is preserved by inserting new wallets at the correct position.
// //
// The original slice is assumed to be already sorted by URL. // The original slice is assumed to be already sorted by URL.
func merge(slice []Wallet, wallets ...Wallet) []Wallet { func merge(slice []accounts.Wallet, wallets ...accounts.Wallet) []accounts.Wallet {
for _, wallet := range wallets { for _, wallet := range wallets {
n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 }) n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 })
if n == len(slice) { if n == len(slice) {
slice = append(slice, wallet) slice = append(slice, wallet)
continue continue
} }
slice = append(slice[:n], append([]Wallet{wallet}, slice[n:]...)...) slice = append(slice[:n], append([]accounts.Wallet{wallet}, slice[n:]...)...)
} }
return slice return slice
} }
// drop is the couterpart of merge, which looks up wallets from within the sorted // drop is the couterpart of merge, which looks up wallets from within the sorted
// cache and removes the ones specified. // cache and removes the ones specified.
func drop(slice []Wallet, wallets ...Wallet) []Wallet { func drop(slice []accounts.Wallet, wallets ...accounts.Wallet) []accounts.Wallet {
for _, wallet := range wallets { for _, wallet := range wallets {
n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 }) n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 })
if n == len(slice) { if n == len(slice) {

View file

@ -41,7 +41,7 @@ type URL struct {
} }
// parseURL converts a user supplied URL into the accounts specific structure. // parseURL converts a user supplied URL into the accounts specific structure.
func parseURL(url string) (URL, error) { func ParseURL(url string) (URL, error) {
parts := strings.Split(url, "://") parts := strings.Split(url, "://")
if len(parts) != 2 || parts[0] == "" { if len(parts) != 2 || parts[0] == "" {
return URL{}, errors.New("protocol scheme missing") return URL{}, errors.New("protocol scheme missing")
@ -81,7 +81,7 @@ func (u *URL) UnmarshalJSON(input []byte) error {
if err != nil { if err != nil {
return err return err
} }
url, err := parseURL(textURL) url, err := ParseURL(textURL)
if err != nil { if err != nil {
return err return err
} }

View file

@ -21,7 +21,7 @@ import (
) )
func TestURLParsing(t *testing.T) { func TestURLParsing(t *testing.T) {
url, err := parseURL("https://ethereum.org") url, err := ParseURL("https://ethereum.org")
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@ -32,7 +32,7 @@ func TestURLParsing(t *testing.T) {
t.Errorf("expected: %v, got: %v", "ethereum.org", url.Path) t.Errorf("expected: %v, got: %v", "ethereum.org", url.Path)
} }
_, err = parseURL("ethereum.org") _, err = ParseURL("ethereum.org")
if err == nil { if err == nil {
t.Error("expected err, got: nil") t.Error("expected err, got: nil")
} }

View file

@ -21,7 +21,7 @@ import (
"errors" "errors"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/manager"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
@ -283,7 +283,7 @@ func (b *EthAPIBackend) EventMux() *event.TypeMux {
return b.eth.EventMux() return b.eth.EventMux()
} }
func (b *EthAPIBackend) AccountManager() *accounts.Manager { func (b *EthAPIBackend) AccountManager() *manager.Manager {
return b.eth.AccountManager() return b.eth.AccountManager()
} }

View file

@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/manager"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
@ -80,7 +81,7 @@ type Ethereum struct {
eventMux *event.TypeMux eventMux *event.TypeMux
engine consensus.Engine engine consensus.Engine
accountManager *accounts.Manager accountManager *manager.Manager
bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports
@ -490,7 +491,7 @@ func (s *Ethereum) StopMining() {
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 }
func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } func (s *Ethereum) AccountManager() *manager.Manager { return s.accountManager }
func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain }
func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } func (s *Ethereum) TxPool() *core.TxPool { return s.txPool }
func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }

View file

@ -28,6 +28,7 @@ import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/accounts/manager"
"github.com/ethereum/go-ethereum/accounts/scwallet" "github.com/ethereum/go-ethereum/accounts/scwallet"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
@ -181,11 +182,11 @@ func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string]string {
// PublicAccountAPI provides an API to access accounts managed by this node. // PublicAccountAPI provides an API to access accounts managed by this node.
// It offers only methods that can retrieve accounts. // It offers only methods that can retrieve accounts.
type PublicAccountAPI struct { type PublicAccountAPI struct {
am *accounts.Manager am *manager.Manager
} }
// NewPublicAccountAPI creates a new PublicAccountAPI. // NewPublicAccountAPI creates a new PublicAccountAPI.
func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI { func NewPublicAccountAPI(am *manager.Manager) *PublicAccountAPI {
return &PublicAccountAPI{am: am} return &PublicAccountAPI{am: am}
} }
@ -198,7 +199,7 @@ func (s *PublicAccountAPI) Accounts() []common.Address {
// It offers methods to create, (un)lock en list accounts. Some methods accept // It offers methods to create, (un)lock en list accounts. Some methods accept
// passwords and are therefore considered private by default. // passwords and are therefore considered private by default.
type PrivateAccountAPI struct { type PrivateAccountAPI struct {
am *accounts.Manager am *manager.Manager
nonceLock *AddrLocker nonceLock *AddrLocker
b Backend b Backend
} }
@ -291,7 +292,7 @@ func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error)
} }
// fetchKeystore retrives the encrypted keystore from the account manager. // fetchKeystore retrives the encrypted keystore from the account manager.
func fetchKeystore(am *accounts.Manager) keystore.KeyStore { func fetchKeystore(am *manager.Manager) keystore.KeyStore {
return am.Backends(keystore.FSKeyStoreType, keystore.DBKeyStoreType)[0].(keystore.KeyStore) return am.Backends(keystore.FSKeyStoreType, keystore.DBKeyStoreType)[0].(keystore.KeyStore)
} }

View file

@ -21,7 +21,7 @@ import (
"context" "context"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/manager"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/bloombits"
@ -43,7 +43,7 @@ type Backend interface {
ProtocolVersion() int ProtocolVersion() int
SuggestPrice(ctx context.Context) (*big.Int, error) SuggestPrice(ctx context.Context) (*big.Int, error)
ChainDb() ethdb.Database ChainDb() ethdb.Database
AccountManager() *accounts.Manager AccountManager() *manager.Manager
ExtRPCEnabled() bool ExtRPCEnabled() bool
RPCGasCap() *big.Int // global gas cap for eth_call over rpc: DoS protection RPCGasCap() *big.Int // global gas cap for eth_call over rpc: DoS protection

View file

@ -21,7 +21,7 @@ import (
"errors" "errors"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/manager"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
@ -252,7 +252,7 @@ func (b *LesApiBackend) ChainDb() ethdb.Database {
return b.eth.chainDb return b.eth.chainDb
} }
func (b *LesApiBackend) AccountManager() *accounts.Manager { func (b *LesApiBackend) AccountManager() *manager.Manager {
return b.eth.accountManager return b.eth.accountManager
} }

View file

@ -20,8 +20,8 @@ package les
import ( import (
"fmt" "fmt"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/manager"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/common/mclock"
@ -64,7 +64,7 @@ type LightEthereum struct {
ApiBackend *LesApiBackend ApiBackend *LesApiBackend
eventMux *event.TypeMux eventMux *event.TypeMux
engine consensus.Engine engine consensus.Engine
accountManager *accounts.Manager accountManager *manager.Manager
netRPCService *ethapi.PublicNetAPI netRPCService *ethapi.PublicNetAPI
} }

View file

@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/external" "github.com/ethereum/go-ethereum/accounts/external"
"github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/accounts/manager"
"github.com/ethereum/go-ethereum/accounts/scwallet" "github.com/ethereum/go-ethereum/accounts/scwallet"
"github.com/ethereum/go-ethereum/accounts/usbwallet" "github.com/ethereum/go-ethereum/accounts/usbwallet"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -463,7 +464,7 @@ func (c *Config) AccountConfig() (int, int, string, error) {
return scryptN, scryptP, keydir, err return scryptN, scryptP, keydir, err
} }
func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { func makeAccountManager(conf *Config) (*manager.Manager, string, error) {
scryptN, scryptP, keydir, err := conf.AccountConfig() scryptN, scryptP, keydir, err := conf.AccountConfig()
var ephemeral string var ephemeral string
if keydir == "" { if keydir == "" {
@ -524,7 +525,7 @@ func makeAccountManager(conf *Config) (*accounts.Manager, string, error) {
} }
} }
return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed}, backends...), ephemeral, nil return manager.NewManager(&manager.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed}, backends...), ephemeral, nil
} }
var warnLock sync.Mutex var warnLock sync.Mutex

View file

@ -26,7 +26,7 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/manager"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
@ -41,7 +41,7 @@ import (
type Node struct { type Node struct {
eventmux *event.TypeMux // Event multiplexer used between the services of a stack eventmux *event.TypeMux // Event multiplexer used between the services of a stack
config *Config config *Config
accman *accounts.Manager accman *manager.Manager
ephemeralKeystore string // if non-empty, the key directory that will be removed by Stop ephemeralKeystore string // if non-empty, the key directory that will be removed by Stop
instanceDirLock fileutil.Releaser // prevents concurrent use of instance directory instanceDirLock fileutil.Releaser // prevents concurrent use of instance directory
@ -566,7 +566,7 @@ func (n *Node) InstanceDir() string {
} }
// AccountManager retrieves the account manager used by the protocol stack. // AccountManager retrieves the account manager used by the protocol stack.
func (n *Node) AccountManager() *accounts.Manager { func (n *Node) AccountManager() *manager.Manager {
return n.accman return n.accman
} }

View file

@ -20,7 +20,7 @@ import (
"path/filepath" "path/filepath"
"reflect" "reflect"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/manager"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
@ -35,7 +35,7 @@ type ServiceContext struct {
config *Config config *Config
services map[reflect.Type]Service // Index of the already constructed services services map[reflect.Type]Service // Index of the already constructed services
EventMux *event.TypeMux // Event multiplexer used for decoupled notifications EventMux *event.TypeMux // Event multiplexer used for decoupled notifications
AccountManager *accounts.Manager // Account manager created by the node. AccountManager *manager.Manager // Account manager created by the node.
} }
// OpenDatabase opens an existing database with the given name (or creates one // OpenDatabase opens an existing database with the given name (or creates one

View file

@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/accounts/manager"
"github.com/ethereum/go-ethereum/accounts/scwallet" "github.com/ethereum/go-ethereum/accounts/scwallet"
"github.com/ethereum/go-ethereum/accounts/usbwallet" "github.com/ethereum/go-ethereum/accounts/usbwallet"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -110,7 +111,7 @@ type Validator interface {
// SignerAPI defines the actual implementation of ExternalAPI // SignerAPI defines the actual implementation of ExternalAPI
type SignerAPI struct { type SignerAPI struct {
chainID *big.Int chainID *big.Int
am *accounts.Manager am *manager.Manager
UI UIClientAPI UI UIClientAPI
validator Validator validator Validator
rejectMode bool rejectMode bool
@ -127,7 +128,7 @@ type Metadata struct {
} }
// StartClefAccountManager initializes and start clef Account Manager // StartClefAccountManager initializes and start clef Account Manager
func StartClefAccountManager(ksLocation string, nousb, lightKDF bool, scpath string) (*accounts.Manager, error) { func StartClefAccountManager(ksLocation string, nousb, lightKDF bool, scpath string) (*manager.Manager, error) {
var ( var (
backends []accounts.Backend backends []accounts.Backend
n, p = keystore.StandardScryptN, keystore.StandardScryptP n, p = keystore.StandardScryptN, keystore.StandardScryptP
@ -202,7 +203,7 @@ func StartClefAccountManager(ksLocation string, nousb, lightKDF bool, scpath str
} }
// Clef doesn't allow insecure http account unlock. // Clef doesn't allow insecure http account unlock.
return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: false}, backends...), nil return manager.NewManager(&manager.Config{InsecureUnlockAllowed: false}, backends...), nil
} }
// MetadataFromContext extracts Metadata from a given context.Context // MetadataFromContext extracts Metadata from a given context.Context
@ -297,7 +298,7 @@ var ErrRequestDenied = errors.New("request denied")
// key that is generated when a new Account is created. // key that is generated when a new Account is created.
// noUSB disables USB support that is required to support hardware devices such as // noUSB disables USB support that is required to support hardware devices such as
// ledger and trezor. // ledger and trezor.
func NewSignerAPI(am *accounts.Manager, chainID int64, noUSB bool, ui UIClientAPI, validator Validator, advancedMode bool, credentials storage.Storage) *SignerAPI { func NewSignerAPI(am *manager.Manager, chainID int64, noUSB bool, ui UIClientAPI, validator Validator, advancedMode bool, credentials storage.Storage) *SignerAPI {
if advancedMode { if advancedMode {
log.Info("Clef is in advanced mode: will warn instead of reject") log.Info("Clef is in advanced mode: will warn instead of reject")
} }
@ -393,16 +394,18 @@ func (api *SignerAPI) startUSBListener() {
// multiple accounts. // multiple accounts.
func (api *SignerAPI) List(ctx context.Context) ([]common.Address, error) { func (api *SignerAPI) List(ctx context.Context) ([]common.Address, error) {
var accs []accounts.Account var accs []accounts.Account
log.Error(fmt.Sprint(len(api.am.Wallets())))
for _, wallet := range api.am.Wallets() { for _, wallet := range api.am.Wallets() {
log.Error(fmt.Sprint(len(wallet.Accounts())))
accs = append(accs, wallet.Accounts()...) accs = append(accs, wallet.Accounts()...)
} }
log.Error(fmt.Sprint(len(accs)))
result, err := api.UI.ApproveListing(&ListRequest{Accounts: accs, Meta: MetadataFromContext(ctx)}) result, err := api.UI.ApproveListing(&ListRequest{Accounts: accs, Meta: MetadataFromContext(ctx)})
if err != nil { if err != nil {
return nil, err return nil, err
} }
if result.Accounts == nil { if result.Accounts == nil {
return nil, ErrRequestDenied return nil, ErrRequestDenied
} }
addresses := make([]common.Address, 0) addresses := make([]common.Address, 0)
for _, acc := range result.Accounts { for _, acc := range result.Accounts {

View file

@ -37,6 +37,8 @@ import (
"github.com/ethereum/go-ethereum/signer/core" "github.com/ethereum/go-ethereum/signer/core"
"github.com/ethereum/go-ethereum/signer/fourbyte" "github.com/ethereum/go-ethereum/signer/fourbyte"
"github.com/ethereum/go-ethereum/signer/storage" "github.com/ethereum/go-ethereum/signer/storage"
_ "github.com/mattn/go-sqlite3"
) )
//Used for testing //Used for testing
@ -232,7 +234,7 @@ func TestNewAcc(t *testing.T) {
testNewAcc(api, control, t) testNewAcc(api, control, t)
// test db keystore // test db keystore
ksLoc := "sqlite3#" + filepath.Join(tmpDir, "test_new_account.db") ksLoc := "testdata/dbconfig.yaml"
api, control = setup(ksLoc, t) api, control = setup(ksLoc, t)
testNewAcc(api, control, t) testNewAcc(api, control, t)
} }
@ -343,7 +345,7 @@ func TestSignTx(t *testing.T) {
testSignTx(api, control, t) testSignTx(api, control, t)
// test db keystore // test db keystore
ksLoc := "sqlite3#" + filepath.Join(tmpDir, "test_sign_tx.db") ksLoc := "testdata/dbconfig.yaml"
api, control = setup(ksLoc, t) api, control = setup(ksLoc, t)
testSignTx(api, control, t) testSignTx(api, control, t)
} }

1
signer/core/testdata/dbconfig.yaml vendored Normal file
View file

@ -0,0 +1 @@
adapter: sqlite3

View file

@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/accounts/manager"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
@ -40,7 +41,7 @@ import (
// registry. // registry.
type UIServerAPI struct { type UIServerAPI struct {
extApi *SignerAPI extApi *SignerAPI
am *accounts.Manager am *manager.Manager
} }
// NewUIServerAPI creates a new UIServerAPI // NewUIServerAPI creates a new UIServerAPI
@ -110,7 +111,7 @@ func (s *UIServerAPI) DeriveAccount(url string, path string, pin *bool) (account
} }
// fetchKeystore retrives the encrypted keystore from the account manager. // fetchKeystore retrives the encrypted keystore from the account manager.
func fetchKeystore(am *accounts.Manager) keystore.KeyStore { func fetchKeystore(am *manager.Manager) keystore.KeyStore {
return am.Backends(keystore.FSKeyStoreType, keystore.DBKeyStoreType)[0].(keystore.KeyStore) return am.Backends(keystore.FSKeyStoreType, keystore.DBKeyStoreType)[0].(keystore.KeyStore)
} }