signer: add mutex around UI

This commit is contained in:
Martin Holst Swende 2017-11-27 13:22:47 +01:00
parent 37552ecc22
commit a601b38e40
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
2 changed files with 85 additions and 76 deletions

View file

@ -36,9 +36,6 @@ import (
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
//type Stringer interface {String()}
type SignerAPI struct { type SignerAPI struct {
chainID *big.Int chainID *big.Int
am *accounts.Manager am *accounts.Manager
@ -52,75 +49,67 @@ type Metadata struct {
scheme string scheme string
} }
type credPreference int // types for the requests/response types
type (
const ( // SignTxRequest contains info about a transaction to sign
forgetPw credPreference = iota SignTxRequest struct {
rememberPwNow
)
type Credentials struct {
password string
}
// SignTxRequest contains info about a transaction to sign
type SignTxRequest struct {
transaction *types.Transaction transaction *types.Transaction
from accounts.Account from accounts.Account
callinfo fmt.Stringer callinfo fmt.Stringer
} }
type SignTxResponse struct { // SignTxResponse result from SignTxRequest
SignTxResponse struct {
hash common.Hash hash common.Hash
approved bool approved bool
pw string pw string
} }
// ExportRequest info about query to export accounts
type ExportRequest struct { ExportRequest struct {
account accounts.Account account accounts.Account
file string file string
} }
type ExportResponse struct { // ExportResponse response to export-request
ExportResponse struct {
approved bool approved bool
} }
// ImportRequest info about request to import an account
type ImportRequest struct { ImportRequest struct {
account accounts.Account account accounts.Account
} }
ImportResponse struct {
type ImportResponse struct {
approved bool approved bool
oldPassword string oldPassword string
newPassword string newPassword string
} }
SignDataRequest struct {
type SignDataRequest struct {
account accounts.Account account accounts.Account
rawdata hexutil.Bytes rawdata hexutil.Bytes
message string message string
hash hexutil.Bytes hash hexutil.Bytes
} }
type SignDataResponse struct { SignDataResponse struct {
approved bool approved bool
pw string pw string
} }
NewAccountRequest struct{}
type NewAccountRequest struct{} NewAccountResponse struct {
type NewAccountResponse struct {
approved bool approved bool
pw string pw string
} }
ListRequest struct {
accounts []Account
}
ListResponse struct {
accounts []Account
}
)
type ListRequest struct { type errorWrapper struct {
accounts []Account
}
type ListResponse struct {
accounts []Account
}
type errorWrapper struct{
msg string msg string
err error err error
} }
func (ew errorWrapper) String() string{
func (ew errorWrapper) String() string {
return fmt.Sprintf("%s\n%s", ew.msg, ew.err) return fmt.Sprintf("%s\n%s", ew.msg, ew.err)
} }
@ -281,16 +270,16 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, from common.Address,
} }
req := SignTxRequest{transaction: tx, from: acc} req := SignTxRequest{transaction: tx, from: acc}
if len(tx.Data()) > 3{ if len(tx.Data()) > 3 {
var abidef string var abidef string
// Try to make sense of the data // Try to make sense of the data
abidef, err = lookupABI(tx.Data()[:4]) abidef, err = lookupABI(tx.Data()[:4])
if err != nil{ if err != nil {
req.callinfo = errorWrapper{"Warning! Could not locate ABI", err} req.callinfo = errorWrapper{"Warning! Could not locate ABI", err}
}else{ } else {
req.callinfo, err = parseCallData(tx.Data(),abidef) req.callinfo, err = parseCallData(tx.Data(), abidef)
if err != nil{ if err != nil {
req.callinfo = errorWrapper{"Warning! Could not validate ABI-data against calldata", err} req.callinfo = errorWrapper{"Warning! Could not validate ABI-data against calldata", err}
} }
} }

View file

@ -24,14 +24,16 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
"sync"
) )
type CommandlineUI struct { type CommandlineUI struct {
in *bufio.Reader in *bufio.Reader
mu sync.Mutex
} }
func NewCommandlineUI() *CommandlineUI { func NewCommandlineUI() *CommandlineUI {
return &CommandlineUI{bufio.NewReader(os.Stdin)} return &CommandlineUI{in: bufio.NewReader(os.Stdin)}
} }
// readString reads a single line from stdin, trimming if from spaces, enforcing // readString reads a single line from stdin, trimming if from spaces, enforcing
@ -76,15 +78,18 @@ func showMetadata(metadata Metadata) {
// ApproveTx prompt the user for confirmation to request to sign transaction // ApproveTx prompt the user for confirmation to request to sign transaction
func (ui *CommandlineUI) ApproveTx(request *SignTxRequest, metadata Metadata, ch chan SignTxResponse) { func (ui *CommandlineUI) ApproveTx(request *SignTxRequest, metadata Metadata, ch chan SignTxResponse) {
ui.mu.Lock()
defer ui.mu.Unlock()
weival := request.transaction.Value() weival := request.transaction.Value()
fmt.Printf("--------- Transaction request-------------\n") fmt.Printf("--------- Transaction request-------------\n")
fmt.Printf("to: %v\n", request.transaction.To().Hex()) fmt.Printf("to: %v\n", request.transaction.To().Hex())
fmt.Printf("from: %v\n", request.from.Address.Hex()) fmt.Printf("from: %v\n", request.from.Address.Hex())
fmt.Printf("value: %v wei\n", weival) fmt.Printf("value: %v wei\n", weival)
if len(request.transaction.Data()) > 0{
fmt.Printf("data: %v\n", common.Bytes2Hex(request.transaction.Data())) fmt.Printf("data: %v\n", common.Bytes2Hex(request.transaction.Data()))
if request.callinfo != nil{ }
if request.callinfo != nil {
fmt.Printf("\nNote: This transaction contains data. Review abi-decoding info below:") fmt.Printf("\nNote: This transaction contains data. Review abi-decoding info below:")
fmt.Printf("\nCall info:\n\t%v\n", request.callinfo.String()) fmt.Printf("\nCall info:\n\t%v\n", request.callinfo.String())
@ -98,6 +103,8 @@ func (ui *CommandlineUI) ApproveTx(request *SignTxRequest, metadata Metadata, ch
// ApproveSignData prompt the user for confirmation to request to sign data // ApproveSignData prompt the user for confirmation to request to sign data
func (ui *CommandlineUI) ApproveSignData(request *SignDataRequest, metadata Metadata, ch chan SignDataResponse) { func (ui *CommandlineUI) ApproveSignData(request *SignDataRequest, metadata Metadata, ch chan SignDataResponse) {
ui.mu.Lock()
defer ui.mu.Unlock()
fmt.Printf("-------- Sign data request--------------\n") fmt.Printf("-------- Sign data request--------------\n")
fmt.Printf("account: %x\n", request.account.Address) fmt.Printf("account: %x\n", request.account.Address)
@ -111,6 +118,9 @@ func (ui *CommandlineUI) ApproveSignData(request *SignDataRequest, metadata Meta
// ApproveExport prompt the user for confirmation to export encrypted account json // ApproveExport prompt the user for confirmation to export encrypted account json
func (ui *CommandlineUI) ApproveExport(request *ExportRequest, metadata Metadata, ch chan ExportResponse) { func (ui *CommandlineUI) ApproveExport(request *ExportRequest, metadata Metadata, ch chan ExportResponse) {
ui.mu.Lock()
defer ui.mu.Unlock()
fmt.Printf("-------- Export account request--------------\n") fmt.Printf("-------- Export account request--------------\n")
fmt.Printf("A request has been made to export the (encrypted) keyfile\n") fmt.Printf("A request has been made to export the (encrypted) keyfile\n")
fmt.Printf("Approving this operation means that the caller obtains the (encrypted) contents\n") fmt.Printf("Approving this operation means that the caller obtains the (encrypted) contents\n")
@ -124,6 +134,9 @@ func (ui *CommandlineUI) ApproveExport(request *ExportRequest, metadata Metadata
// ApproveImport prompt the user for confirmation to import account json // ApproveImport prompt the user for confirmation to import account json
func (ui *CommandlineUI) ApproveImport(request *ImportRequest, metadata Metadata, ch chan ImportResponse) { func (ui *CommandlineUI) ApproveImport(request *ImportRequest, metadata Metadata, ch chan ImportResponse) {
ui.mu.Lock()
defer ui.mu.Unlock()
fmt.Printf("-------- Export account request--------------\n") fmt.Printf("-------- Export account request--------------\n")
fmt.Printf("A request has been made to import an encrypted keyfile\n") fmt.Printf("A request has been made to import an encrypted keyfile\n")
fmt.Printf("-------------------------------------------\n") fmt.Printf("-------------------------------------------\n")
@ -135,6 +148,9 @@ func (ui *CommandlineUI) ApproveImport(request *ImportRequest, metadata Metadata
// the list of accounts to list can be modified by the ui // the list of accounts to list can be modified by the ui
func (ui *CommandlineUI) ApproveListing(request *ListRequest, metadata Metadata, ch chan ListResponse) { func (ui *CommandlineUI) ApproveListing(request *ListRequest, metadata Metadata, ch chan ListResponse) {
ui.mu.Lock()
defer ui.mu.Unlock()
fmt.Printf("-------- List account request--------------\n") fmt.Printf("-------- List account request--------------\n")
fmt.Printf("A request has been made to list all accounts. \n") fmt.Printf("A request has been made to list all accounts. \n")
fmt.Printf("You can select which accounts the caller can see\n") fmt.Printf("You can select which accounts the caller can see\n")
@ -152,6 +168,10 @@ func (ui *CommandlineUI) ApproveListing(request *ListRequest, metadata Metadata,
// ApproveNewAccount prompt the user for confirmation to create new account, and reveal to caller // ApproveNewAccount prompt the user for confirmation to create new account, and reveal to caller
func (ui *CommandlineUI) ApproveNewAccount(requst *NewAccountRequest, metadata Metadata, ch chan NewAccountResponse) { func (ui *CommandlineUI) ApproveNewAccount(requst *NewAccountRequest, metadata Metadata, ch chan NewAccountResponse) {
ui.mu.Lock()
defer ui.mu.Unlock()
fmt.Printf("-------- New account request--------------\n") fmt.Printf("-------- New account request--------------\n")
fmt.Printf("A request has been made to create a new. \n") fmt.Printf("A request has been made to create a new. \n")
fmt.Printf("Approving this operation means that a new account is created,\n") fmt.Printf("Approving this operation means that a new account is created,\n")