wip: basic relaying to clef

This commit is contained in:
Martin Holst Swende 2018-05-20 20:12:20 +02:00
parent 212bba47ff
commit 255ef1c81f
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
2 changed files with 72 additions and 7 deletions

View file

@ -206,20 +206,33 @@ type PrivateAccountAPI struct {
am *accounts.Manager am *accounts.Manager
nonceLock *AddrLocker nonceLock *AddrLocker
b Backend b Backend
extapi *ExternalSignerAPI // external signer, nil if not used
} }
// NewPrivateAccountAPI create a new PrivateAccountAPI. // NewPrivateAccountAPI create a new PrivateAccountAPI.
func NewPrivateAccountAPI(b Backend, nonceLock *AddrLocker) *PrivateAccountAPI { func NewPrivateAccountAPI(b Backend, nonceLock *AddrLocker) *PrivateAccountAPI {
extapi, _ := NewExternalSigner()
return &PrivateAccountAPI{ return &PrivateAccountAPI{
am: b.AccountManager(), am: b.AccountManager(),
nonceLock: nonceLock, nonceLock: nonceLock,
b: b, b: b,
extapi:extapi,
} }
} }
// ListAccounts will return a list of addresses for accounts this node manages. // ListAccounts will return a list of addresses for accounts this node manages.
func (s *PrivateAccountAPI) ListAccounts() []common.Address { func (s *PrivateAccountAPI) ListAccounts() []common.Address {
addresses := make([]common.Address, 0) // return [] instead of nil if empty addresses := make([]common.Address, 0) // return [] instead of nil if empty
if s.extapi != nil{
if accounts, err := s.extapi.listAccounts(); err == nil{
for _, account := range accounts {
addresses = append(addresses, account.Address)
}
}
return addresses
}
for _, wallet := range s.am.Wallets() { for _, wallet := range s.am.Wallets() {
for _, account := range wallet.Accounts() { for _, account := range wallet.Accounts() {
addresses = append(addresses, account.Address) addresses = append(addresses, account.Address)
@ -340,16 +353,25 @@ func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool {
// NOTE: the caller needs to ensure that the nonceLock is held, if applicable, // NOTE: the caller needs to ensure that the nonceLock is held, if applicable,
// and release it after the transaction has been submitted to the tx pool // and release it after the transaction has been submitted to the tx pool
func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args SendTxArgs, passwd string) (*types.Transaction, error) { func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args SendTxArgs, passwd string) (*types.Transaction, error) {
// Set some sanity defaults and terminate on failure
if err := args.setDefaults(ctx, s.b); err != nil {
return nil, err
}
if true{
extapi, err := NewExternalSigner()
if err != nil {
return nil, err
}
tx, err := extapi.signTransaction(ctx, args)
return tx, err
}
// Look up the wallet containing the requested signer // Look up the wallet containing the requested signer
account := accounts.Account{Address: args.From} account := accounts.Account{Address: args.From}
wallet, err := s.am.Find(account) wallet, err := s.am.Find(account)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Set some sanity defaults and terminate on failure
if err := args.setDefaults(ctx, s.b); err != nil {
return nil, err
}
// Assemble the transaction and sign with the wallet // Assemble the transaction and sign with the wallet
tx := args.toTransaction() tx := args.toTransaction()
@ -943,11 +965,12 @@ func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransa
type PublicTransactionPoolAPI struct { type PublicTransactionPoolAPI struct {
b Backend b Backend
nonceLock *AddrLocker nonceLock *AddrLocker
extapi *ExternalSignerAPI // external signer, nil if not used
} }
// NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool. // NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool.
func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransactionPoolAPI { func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransactionPoolAPI {
return &PublicTransactionPoolAPI{b, nonceLock} return &PublicTransactionPoolAPI{b, nonceLock, nil}
} }
// GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number.
@ -1288,7 +1311,14 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Sen
if err := args.setDefaults(ctx, s.b); err != nil { if err := args.setDefaults(ctx, s.b); err != nil {
return nil, err return nil, err
} }
tx, err := s.sign(args.From, args.toTransaction())
extapi, err := NewExternalSigner()
if err != nil {
return nil, err
}
tx, err := extapi.signTransaction(ctx, args)
//tx, err := s.sign(args.From, args.toTransaction())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1489,3 +1519,35 @@ func (s *PublicNetAPI) PeerCount() hexutil.Uint {
func (s *PublicNetAPI) Version() string { func (s *PublicNetAPI) Version() string {
return fmt.Sprintf("%d", s.networkVersion) return fmt.Sprintf("%d", s.networkVersion)
} }
// ExternalSignerAPI provides an API to interact with an external signer (clef)
// It proxies request to the external signer while forwarding relevant
// request headers
type ExternalSignerAPI struct {
client *rpc.Client
}
func NewExternalSigner() (*ExternalSignerAPI, error) {
client, err := rpc.DialHTTP("http://localhost:8550")
if err != nil {
return nil, err
}
return &ExternalSignerAPI{
client: client,
}, nil
}
func (api *ExternalSignerAPI) signTransaction(ctx context.Context, args SendTxArgs) (*types.Transaction, error) {
res := SignTransactionResult{}
if err := api.client.Call(&res, "account_signTransaction", args); err != nil {
return nil, err
}
return res.Tx, nil
}
func (api *ExternalSignerAPI) listAccounts() ([]accounts.Account, error) {
var res []accounts.Account
if err := api.client.Call(&res, "account_list"); err != nil {
return nil, err
}
return res, nil
}

View file

@ -113,6 +113,9 @@ func (ui *CommandlineUI) ApproveTx(request *SignTxRequest) (SignTxResponse, erro
} }
fmt.Printf("from: %v\n", request.Transaction.From.String()) fmt.Printf("from: %v\n", request.Transaction.From.String())
fmt.Printf("value: %v wei\n", weival) fmt.Printf("value: %v wei\n", weival)
fmt.Printf("gas: %v\n", request.Transaction.Gas)
fmt.Printf("gasprice: %v wei\n", request.Transaction.GasPrice)
fmt.Printf("nonce: %v\n", request.Transaction.Nonce)
if request.Transaction.Data != nil { if request.Transaction.Data != nil {
d := *request.Transaction.Data d := *request.Transaction.Data
if len(d) > 0 { if len(d) > 0 {
@ -122,7 +125,7 @@ func (ui *CommandlineUI) ApproveTx(request *SignTxRequest) (SignTxResponse, erro
if request.Callinfo != nil { if request.Callinfo != nil {
fmt.Printf("\nTransaction validation:\n") fmt.Printf("\nTransaction validation:\n")
for _, m := range request.Callinfo { for _, m := range request.Callinfo {
fmt.Printf(" * %s : %s", m.Typ, m.Message) fmt.Printf(" * %s : %s\n", m.Typ, m.Message)
} }
fmt.Println() fmt.Println()