mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
refactor move manager.go into seperated package to avoid cyclic import
This commit is contained in:
parent
7f6c0fb601
commit
276e13dc01
19 changed files with 115 additions and 71 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 }
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
1
signer/core/testdata/dbconfig.yaml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
adapter: sqlite3
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue