signer: implement account_Version on external API

This commit is contained in:
Martin Holst Swende 2018-11-11 17:21:01 +01:00
parent 22633db7c9
commit 9838abaca4
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
4 changed files with 49 additions and 38 deletions

View file

@ -1,7 +1,6 @@
package external
import (
"errors"
"fmt"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts"
@ -31,7 +30,7 @@ func NewExternalBackend(endpoint string) (*ExternalBackend, error) {
return nil, err
}
return &ExternalBackend{
signers: []accounts.Wallet{ signer},
signers: []accounts.Wallet{signer},
}, nil
}
@ -48,6 +47,7 @@ func (eb *ExternalBackend) Subscribe(sink chan<- accounts.WalletEvent) event.Sub
type ExternalSigner struct {
client *rpc.Client
endpoint string
status string
cacheMu sync.RWMutex
cache []accounts.Account
}
@ -57,10 +57,17 @@ func NewExternalSigner(endpoint string) (*ExternalSigner, error) {
if err != nil {
return nil, err
}
return &ExternalSigner{
extsigner := &ExternalSigner{
client: client,
endpoint: endpoint,
}, nil
}
// Check if reachable
version, err := extsigner.pingVersion()
if err != nil {
return nil, err
}
extsigner.status = fmt.Sprintf("ok [version=%v]", version)
return extsigner, nil
}
func (api *ExternalSigner) URL() accounts.URL {
@ -71,7 +78,7 @@ func (api *ExternalSigner) URL() accounts.URL {
}
func (api *ExternalSigner) Status() (string, error) {
return "ok", nil
return api.status, nil
}
func (api *ExternalSigner) Open(passphrase string) error {
@ -107,8 +114,8 @@ func (api *ExternalSigner) Accounts() []accounts.Account {
func (api *ExternalSigner) Contains(account accounts.Account) bool {
api.cacheMu.RLock()
defer api.cacheMu.RUnlock()
for _, a := range api.cache{
if a.Address == account.Address && (account.URL == (accounts.URL{}) || account.URL == api.URL()){
for _, a := range api.cache {
if a.Address == account.Address && (account.URL == (accounts.URL{}) || account.URL == api.URL()) {
return true
}
}
@ -134,11 +141,10 @@ func (api *ExternalSigner) SignCliqueHeader(account accounts.Account, header *ty
return api.signHash(account, accounts.CliqueHash(header).Bytes())
}
func (api *ExternalSigner) SignText(account accounts.Account, text []byte)([]byte, error){
func (api *ExternalSigner) SignText(account accounts.Account, text []byte) ([]byte, error) {
return api.signHash(account, accounts.TextHash(text))
}
func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
res := ethapi.SignTransactionResult{}
to := common.NewMixedcaseAddress(*tx.To())
@ -174,17 +180,8 @@ func (api *ExternalSigner) listAccounts() ([]common.Address, error) {
}
return res, nil
}
func (api *ExternalSigner) newAccount() (common.Address, error) {
var res accounts.Account
if err := api.client.Call(&res, "account_new"); err != nil {
return common.Address{}, err
}
return res.Address, nil
}
func (api *ExternalSigner) signCliqueBlock(a common.Address, rlpBlock hexutil.Bytes) (hexutil.Bytes, error) {
if api == nil {
return nil, errors.New("External API not initialized")
}
var sig hexutil.Bytes
if err := api.client.Call(&sig, "account_signData", "application/clique", a, rlpBlock); err != nil {
return nil, err
@ -195,3 +192,11 @@ func (api *ExternalSigner) signCliqueBlock(a common.Address, rlpBlock hexutil.By
sig[64] -= 27 // Transform V from 27/28 to 0/1 for Clique use
return sig, nil
}
func (api *ExternalSigner) pingVersion() (string, error) {
var v string
if err := api.client.Call(&v, "account_version"); err != nil {
return "", err
}
return v, nil
}

View file

@ -49,12 +49,6 @@ import (
"gopkg.in/urfave/cli.v1"
)
// ExternalAPIVersion -- see extapi_changelog.md
const ExternalAPIVersion = "4.0.0"
// InternalAPIVersion -- see intapi_changelog.md
const InternalAPIVersion = "3.0.0"
const legalWarning = `
WARNING!
@ -479,8 +473,8 @@ func signer(c *cli.Context) error {
}
ui.OnSignerStartup(core.StartupInfo{
Info: map[string]interface{}{
"extapi_version": ExternalAPIVersion,
"intapi_version": InternalAPIVersion,
"extapi_version": core.ExternalAPIVersion,
"intapi_version": core.InternalAPIVersion,
"extapi_http": extapiURL,
"extapi_ipc": ipcapiURL,
},

View file

@ -36,8 +36,14 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
// numberOfAccountsToDerive For hardware wallets, the number of accounts to derive
const numberOfAccountsToDerive = 10
const (
// numberOfAccountsToDerive For hardware wallets, the number of accounts to derive
numberOfAccountsToDerive = 10
// ExternalAPIVersion -- see extapi_changelog.md
ExternalAPIVersion = "4.0.0"
// InternalAPIVersion -- see intapi_changelog.md
InternalAPIVersion = "3.0.0"
)
// ExternalAPI defines the external API through which signing requests are made.
type ExternalAPI interface {
@ -47,7 +53,7 @@ type ExternalAPI interface {
New(ctx context.Context) (accounts.Account, error)
// SignTransaction request to sign the specified transaction
SignTransaction(ctx context.Context, args SendTxArgs, methodSelector *string) (*ethapi.SignTransactionResult, error)
// Sign - request to sign the given data (plus prefix)
// Sign - resquest to sign the given data (plus prefix)
Sign(ctx context.Context, addr common.MixedcaseAddress, data hexutil.Bytes) (hexutil.Bytes, error)
// Export - request to export an account
Export(ctx context.Context, addr common.Address) (json.RawMessage, error)
@ -55,6 +61,7 @@ type ExternalAPI interface {
// Should be moved to Internal API, in next phase when we have
// bi-directional communication
//Import(ctx context.Context, keyJSON json.RawMessage) (Account, error)
Version(ctx context.Context) (string, error)
}
// SignerUI specifies what method a UI needs to implement to be able to be used as a UI for the signer
@ -610,3 +617,9 @@ func (api *SignerAPI) Import(ctx context.Context, keyJSON json.RawMessage) (Acco
}
return Account{Typ: "Account", URL: acc.URL, Address: acc.Address}, nil
}
// Returns the external api version. This method does not require user acceptance. Available methods are
// available via enumeration anyway, and this info does not contain user-specific data
func (api *SignerAPI) Version(ctx context.Context) (string, error) {
return ExternalAPIVersion, nil
}

View file

@ -80,14 +80,13 @@ func (l *AuditLogger) Export(ctx context.Context, addr common.Address) (json.Raw
return j, e
}
//func (l *AuditLogger) Import(ctx context.Context, keyJSON json.RawMessage) (Account, error) {
// // Don't actually log the json contents
// l.log.Info("Import", "type", "request", "metadata", MetadataFromContext(ctx).String(),
// "keyJSON size", len(keyJSON))
// a, e := l.api.Import(ctx, keyJSON)
// l.log.Info("Import", "type", "response", "addr", a.String(), "error", e)
// return a, e
//}
func (l *AuditLogger) Version(ctx context.Context) (string, error) {
l.log.Info("Version", "type", "request", "metadata", MetadataFromContext(ctx).String())
data, err := l.api.Version(ctx)
l.log.Info("Version", "type", "response", "data", data, "error", err)
return data, err
}
func NewAuditLogger(path string, api ExternalAPI) (*AuditLogger, error) {
l := log.New("api", "signer")